linux/arch/x86/kernel/genx2apic_phys.c
<<
>>
Prefs
   1#include <linux/threads.h>
   2#include <linux/cpumask.h>
   3#include <linux/string.h>
   4#include <linux/kernel.h>
   5#include <linux/ctype.h>
   6#include <linux/init.h>
   7#include <linux/dmar.h>
   8
   9#include <asm/smp.h>
  10#include <asm/ipi.h>
  11#include <asm/genapic.h>
  12
  13static int x2apic_phys;
  14
  15static int set_x2apic_phys_mode(char *arg)
  16{
  17        x2apic_phys = 1;
  18        return 0;
  19}
  20early_param("x2apic_phys", set_x2apic_phys_mode);
  21
  22static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
  23{
  24        if (cpu_has_x2apic && x2apic_phys)
  25                return 1;
  26
  27        return 0;
  28}
  29
  30/* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */
  31
  32static cpumask_t x2apic_target_cpus(void)
  33{
  34        return cpumask_of_cpu(0);
  35}
  36
  37static cpumask_t x2apic_vector_allocation_domain(int cpu)
  38{
  39        cpumask_t domain = CPU_MASK_NONE;
  40        cpu_set(cpu, domain);
  41        return domain;
  42}
  43
  44static void __x2apic_send_IPI_dest(unsigned int apicid, int vector,
  45                                   unsigned int dest)
  46{
  47        unsigned long cfg;
  48
  49        cfg = __prepare_ICR(0, vector, dest);
  50
  51        /*
  52         * send the IPI.
  53         */
  54        x2apic_icr_write(cfg, apicid);
  55}
  56
  57static void x2apic_send_IPI_mask(cpumask_t mask, int vector)
  58{
  59        unsigned long flags;
  60        unsigned long query_cpu;
  61
  62        local_irq_save(flags);
  63        for_each_cpu_mask(query_cpu, mask) {
  64                __x2apic_send_IPI_dest(per_cpu(x86_cpu_to_apicid, query_cpu),
  65                                       vector, APIC_DEST_PHYSICAL);
  66        }
  67        local_irq_restore(flags);
  68}
  69
  70static void x2apic_send_IPI_allbutself(int vector)
  71{
  72        cpumask_t mask = cpu_online_map;
  73
  74        cpu_clear(smp_processor_id(), mask);
  75
  76        if (!cpus_empty(mask))
  77                x2apic_send_IPI_mask(mask, vector);
  78}
  79
  80static void x2apic_send_IPI_all(int vector)
  81{
  82        x2apic_send_IPI_mask(cpu_online_map, vector);
  83}
  84
  85static int x2apic_apic_id_registered(void)
  86{
  87        return 1;
  88}
  89
  90static unsigned int x2apic_cpu_mask_to_apicid(cpumask_t cpumask)
  91{
  92        int cpu;
  93
  94        /*
  95         * We're using fixed IRQ delivery, can only return one phys APIC ID.
  96         * May as well be the first.
  97         */
  98        cpu = first_cpu(cpumask);
  99        if ((unsigned)cpu < NR_CPUS)
 100                return per_cpu(x86_cpu_to_apicid, cpu);
 101        else
 102                return BAD_APICID;
 103}
 104
 105static unsigned int get_apic_id(unsigned long x)
 106{
 107        unsigned int id;
 108
 109        id = x;
 110        return id;
 111}
 112
 113static unsigned long set_apic_id(unsigned int id)
 114{
 115        unsigned long x;
 116
 117        x = id;
 118        return x;
 119}
 120
 121static unsigned int phys_pkg_id(int index_msb)
 122{
 123        return current_cpu_data.initial_apicid >> index_msb;
 124}
 125
 126void x2apic_send_IPI_self(int vector)
 127{
 128        apic_write(APIC_SELF_IPI, vector);
 129}
 130
 131void init_x2apic_ldr(void)
 132{
 133        return;
 134}
 135
 136struct genapic apic_x2apic_phys = {
 137        .name = "physical x2apic",
 138        .acpi_madt_oem_check = x2apic_acpi_madt_oem_check,
 139        .int_delivery_mode = dest_Fixed,
 140        .int_dest_mode = (APIC_DEST_PHYSICAL != 0),
 141        .target_cpus = x2apic_target_cpus,
 142        .vector_allocation_domain = x2apic_vector_allocation_domain,
 143        .apic_id_registered = x2apic_apic_id_registered,
 144        .init_apic_ldr = init_x2apic_ldr,
 145        .send_IPI_all = x2apic_send_IPI_all,
 146        .send_IPI_allbutself = x2apic_send_IPI_allbutself,
 147        .send_IPI_mask = x2apic_send_IPI_mask,
 148        .send_IPI_self = x2apic_send_IPI_self,
 149        .cpu_mask_to_apicid = x2apic_cpu_mask_to_apicid,
 150        .phys_pkg_id = phys_pkg_id,
 151        .get_apic_id = get_apic_id,
 152        .set_apic_id = set_apic_id,
 153        .apic_id_mask = (0xFFFFFFFFu),
 154};
 155
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.