Print this page
patch use-x2apic-feature
patch apic-simplify
patch apic-task-reg-write-dup


  77 static apic_reg_ops_t x2apic_regs_ops = {
  78         local_x2apic_read,
  79         local_x2apic_write,
  80         get_local_x2apic_pri,
  81         local_x2apic_write_task_reg,
  82         local_x2apic_write_int_cmd,
  83         apic_send_EOI,
  84 };
  85 
  86 int apic_have_32bit_cr8 = 0;
  87 
  88 /* The default ops is local APIC (Memory Mapped IO) */
  89 apic_reg_ops_t *apic_reg_ops = &local_apic_regs_ops;
  90 
  91 /*
  92  * APIC register ops related data sturctures and functions.
  93  */
  94 void apic_send_EOI();
  95 void apic_send_directed_EOI(uint32_t irq);
  96 
  97 #define X2APIC_CPUID_BIT        21
  98 #define X2APIC_ENABLE_BIT       10
  99 
 100 /*
 101  * Local APIC Implementation
 102  */
 103 static uint64_t
 104 local_apic_read(uint32_t reg)
 105 {
 106         return ((uint32_t)apicadr[reg]);
 107 }
 108 
 109 static void
 110 local_apic_write(uint32_t reg, uint64_t value)
 111 {
 112         apicadr[reg] = (uint32_t)value;
 113 }
 114 
 115 static int
 116 get_local_apic_pri(void)
 117 {
 118 #if defined(__amd64)
 119         return ((int)getcr8());
 120 #else
 121         if (apic_have_32bit_cr8)
 122                 return ((int)getcr8());
 123         return (apicadr[APIC_TASK_REG]);
 124 #endif
 125 }
 126 
 127 static void
 128 local_apic_write_task_reg(uint64_t value)
 129 {
 130 #if defined(__amd64)
 131         setcr8((ulong_t)(value >> APIC_IPL_SHIFT));
 132 #else
 133         if (apic_have_32bit_cr8)
 134                 setcr8((ulong_t)(value >> APIC_IPL_SHIFT));
 135         else
 136                 apicadr[APIC_TASK_REG] = (uint32_t)value;
 137 #endif
 138 }
 139 
 140 static void
 141 local_apic_write_int_cmd(uint32_t cpu_id, uint32_t cmd1)
 142 {
 143         apicadr[APIC_INT_CMD2] = cpu_id << APIC_ICR_ID_BIT_OFFSET;
 144         apicadr[APIC_INT_CMD1] = cmd1;
 145 }
 146 
 147 /*
 148  * X2APIC Implementation.
 149  */
 150 static uint64_t
 151 local_x2apic_read(uint32_t msr)
 152 {
 153         uint64_t i;
 154 
 155         i = (uint64_t)(rdmsr(REG_X2APIC_BASE_MSR + (msr >> 2)) & 0xffffffff);
 156         return (i);


 216          *
 217          * A broadcast EOI is not generated.
 218          */
 219         apic_reg_ops->apic_write(APIC_EOI_REG, 0);
 220 
 221         apic_irq = apic_irq_table[irq];
 222         while (apic_irq) {
 223                 intr_index = apic_irq->airq_mps_intr_index;
 224                 if (intr_index == ACPI_INDEX || intr_index >= 0) {
 225                         ioapicindex = apic_irq->airq_ioapicindex;
 226                         vector = apic_irq->airq_vector;
 227                         ioapic_write_eoi(ioapicindex, vector);
 228                 }
 229                 apic_irq = apic_irq->airq_next;
 230         }
 231 }
 232 
 233 int
 234 apic_detect_x2apic(void)
 235 {
 236         struct cpuid_regs cp;
 237 
 238         if (x2apic_enable == 0)
 239                 return (0);
 240 
 241         cp.cp_eax = 1;
 242         (void) __cpuid_insn(&cp);
 243 
 244         return ((cp.cp_ecx & (0x1 << X2APIC_CPUID_BIT)) ? 1 : 0);
 245 }
 246 
 247 void
 248 apic_enable_x2apic(void)
 249 {
 250         uint64_t apic_base_msr;
 251 
 252         if (apic_local_mode() == LOCAL_X2APIC) {
 253                 /* BIOS apparently has enabled X2APIC */
 254                 if (apic_mode != LOCAL_X2APIC)
 255                         x2apic_update_psm();
 256                 return;
 257         }
 258 
 259         /*
 260          * This is the first time we are enabling X2APIC on this CPU
 261          */
 262         apic_base_msr = rdmsr(REG_APIC_BASE_MSR);
 263         apic_base_msr = apic_base_msr | (0x1 << X2APIC_ENABLE_BIT);
 264         wrmsr(REG_APIC_BASE_MSR, apic_base_msr);




  77 static apic_reg_ops_t x2apic_regs_ops = {
  78         local_x2apic_read,
  79         local_x2apic_write,
  80         get_local_x2apic_pri,
  81         local_x2apic_write_task_reg,
  82         local_x2apic_write_int_cmd,
  83         apic_send_EOI,
  84 };
  85 
  86 int apic_have_32bit_cr8 = 0;
  87 
  88 /* The default ops is local APIC (Memory Mapped IO) */
  89 apic_reg_ops_t *apic_reg_ops = &local_apic_regs_ops;
  90 
  91 /*
  92  * APIC register ops related data sturctures and functions.
  93  */
  94 void apic_send_EOI();
  95 void apic_send_directed_EOI(uint32_t irq);
  96 

  97 #define X2APIC_ENABLE_BIT       10
  98 
  99 /*
 100  * Local APIC Implementation
 101  */
 102 static uint64_t
 103 local_apic_read(uint32_t reg)
 104 {
 105         return ((uint32_t)apicadr[reg]);
 106 }
 107 
 108 static void
 109 local_apic_write(uint32_t reg, uint64_t value)
 110 {
 111         LOCAL_APIC_WRITE_REG(reg, (uint32_t)value);
 112 }
 113 
 114 static int
 115 get_local_apic_pri(void)
 116 {
 117 #if defined(__amd64)
 118         return ((int)getcr8());
 119 #else
 120         if (apic_have_32bit_cr8)
 121                 return ((int)getcr8());
 122         return (apicadr[APIC_TASK_REG]);
 123 #endif
 124 }
 125 
 126 static void
 127 local_apic_write_task_reg(uint64_t value)
 128 {
 129 #if defined(__amd64)
 130         setcr8((ulong_t)(value >> APIC_IPL_SHIFT));
 131 #else
 132         if (apic_have_32bit_cr8)
 133                 setcr8((ulong_t)(value >> APIC_IPL_SHIFT));
 134         else
 135                 LOCAL_APIC_WRITE_REG(APIC_TASK_REG, (uint32_t)value);
 136 #endif
 137 }
 138 
 139 static void
 140 local_apic_write_int_cmd(uint32_t cpu_id, uint32_t cmd1)
 141 {
 142         apicadr[APIC_INT_CMD2] = cpu_id << APIC_ICR_ID_BIT_OFFSET;
 143         apicadr[APIC_INT_CMD1] = cmd1;
 144 }
 145 
 146 /*
 147  * X2APIC Implementation.
 148  */
 149 static uint64_t
 150 local_x2apic_read(uint32_t msr)
 151 {
 152         uint64_t i;
 153 
 154         i = (uint64_t)(rdmsr(REG_X2APIC_BASE_MSR + (msr >> 2)) & 0xffffffff);
 155         return (i);


 215          *
 216          * A broadcast EOI is not generated.
 217          */
 218         apic_reg_ops->apic_write(APIC_EOI_REG, 0);
 219 
 220         apic_irq = apic_irq_table[irq];
 221         while (apic_irq) {
 222                 intr_index = apic_irq->airq_mps_intr_index;
 223                 if (intr_index == ACPI_INDEX || intr_index >= 0) {
 224                         ioapicindex = apic_irq->airq_ioapicindex;
 225                         vector = apic_irq->airq_vector;
 226                         ioapic_write_eoi(ioapicindex, vector);
 227                 }
 228                 apic_irq = apic_irq->airq_next;
 229         }
 230 }
 231 
 232 int
 233 apic_detect_x2apic(void)
 234 {


 235         if (x2apic_enable == 0)
 236                 return (0);
 237 
 238         return is_x86_feature(x86_featureset, X86FSET_X2APIC);



 239 }
 240 
 241 void
 242 apic_enable_x2apic(void)
 243 {
 244         uint64_t apic_base_msr;
 245 
 246         if (apic_local_mode() == LOCAL_X2APIC) {
 247                 /* BIOS apparently has enabled X2APIC */
 248                 if (apic_mode != LOCAL_X2APIC)
 249                         x2apic_update_psm();
 250                 return;
 251         }
 252 
 253         /*
 254          * This is the first time we are enabling X2APIC on this CPU
 255          */
 256         apic_base_msr = rdmsr(REG_APIC_BASE_MSR);
 257         apic_base_msr = apic_base_msr | (0x1 << X2APIC_ENABLE_BIT);
 258         wrmsr(REG_APIC_BASE_MSR, apic_base_msr);