Print this page
8620 pcplusmp shouldn't support x2APIC mode
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/i86pc/io/apix/apix.c
          +++ new/usr/src/uts/i86pc/io/apix/apix.c
↓ open down ↓ 213 lines elided ↑ open up ↑
 214  214  processorid_t *apix_major_to_cpu;       /* major to cpu mapping */
 215  215  kmutex_t apix_mutex;    /* for apix_dev_vector & apix_major_to_cpu */
 216  216  
 217  217  int apix_nipis = 16;    /* Maximum number of IPIs */
 218  218  /*
 219  219   * Maximum number of vectors in a CPU that can be used for interrupt
 220  220   * allocation (including IPIs and the reserved vectors).
 221  221   */
 222  222  int apix_cpu_nvectors = APIX_NVECTOR;
 223  223  
      224 +/* number of CPUs in power-on transition state */
      225 +static int apic_poweron_cnt = 0;
      226 +
 224  227  /* gcpu.h */
 225  228  
 226  229  extern void apic_do_interrupt(struct regs *rp, trap_trace_rec_t *ttp);
 227  230  extern void apic_change_eoi();
 228  231  
 229  232  /*
 230  233   *      This is the loadable module wrapper
 231  234   */
 232  235  
 233  236  int
↓ open down ↓ 2319 lines elided ↑ open up ↑
2553 2556          /* get the IRQ number */
2554 2557          if ((irqno = apix_intx_xlate_irq(dip, inum, ispec)) == -1)
2555 2558                  return (NULL);
2556 2559  
2557 2560          /* get the vector number if a vector is allocated to this irqno */
2558 2561          vecp = apix_intx_get_vector(irqno);
2559 2562  
2560 2563          return (vecp);
2561 2564  }
2562 2565  
     2566 +/*
     2567 + * Switch between safe and x2APIC IPI sending method.
     2568 + * The CPU may power on in xapic mode or x2apic mode. If the CPU needs to send
     2569 + * an IPI to other CPUs before entering x2APIC mode, it still needs to use the
     2570 + * xAPIC method. Before sending a StartIPI to the target CPU, psm_send_ipi will
     2571 + * be changed to apic_common_send_ipi, which detects current local APIC mode and
     2572 + * use the right method to send an IPI. If some CPUs fail to start up,
     2573 + * apic_poweron_cnt won't return to zero, so apic_common_send_ipi will always be
     2574 + * used. psm_send_ipi can't be simply changed back to x2apic_send_ipi if some
     2575 + * CPUs failed to start up because those failed CPUs may recover itself later at
     2576 + * unpredictable time.
     2577 + */
     2578 +void
     2579 +apic_switch_ipi_callback(boolean_t enter)
     2580 +{
     2581 +        ulong_t iflag;
     2582 +        struct psm_ops *pops = psmops;
     2583 +
     2584 +        iflag = intr_clear();
     2585 +        lock_set(&apic_mode_switch_lock);
     2586 +        if (enter) {
     2587 +                ASSERT(apic_poweron_cnt >= 0);
     2588 +                if (apic_poweron_cnt == 0) {
     2589 +                        pops->psm_send_ipi = apic_common_send_ipi;
     2590 +                        send_dirintf = pops->psm_send_ipi;
     2591 +                }
     2592 +                apic_poweron_cnt++;
     2593 +        } else {
     2594 +                ASSERT(apic_poweron_cnt > 0);
     2595 +                apic_poweron_cnt--;
     2596 +                if (apic_poweron_cnt == 0) {
     2597 +                        pops->psm_send_ipi = x2apic_send_ipi;
     2598 +                        send_dirintf = pops->psm_send_ipi;
     2599 +                }
     2600 +        }
     2601 +        lock_clear(&apic_mode_switch_lock);
     2602 +        intr_restore(iflag);
     2603 +}
     2604 +
2563 2605  /* stub function */
2564 2606  int
2565 2607  apix_loaded(void)
2566 2608  {
2567 2609          return (apix_is_enabled);
2568 2610  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX