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>
        
*** 98,108 ****
  static void     apic_init(void);
  static void     apic_picinit(void);
  static int      apic_post_cpu_start(void);
  static int      apic_intr_enter(int ipl, int *vect);
  static void     apic_setspl(int ipl);
- static void     x2apic_setspl(int ipl);
  static int      apic_addspl(int ipl, int vector, int min_ipl, int max_ipl);
  static int      apic_delspl(int ipl, int vector, int min_ipl, int max_ipl);
  static int      apic_disable_intr(processorid_t cpun);
  static void     apic_enable_intr(processorid_t cpun);
  static int              apic_get_ipivect(int ipl, int type);
--- 98,107 ----
*** 310,334 ****
          uint_t nlvt;
          uint32_t svr = AV_UNIT_ENABLE | APIC_SPUR_INTR;
  
          apic_reg_ops->apic_write_task_reg(APIC_MASK_ALL);
  
!         if (apic_mode == LOCAL_APIC) {
                  /*
                   * We are running APIC in MMIO mode.
                   */
                  if (apic_flat_model) {
!                         apic_reg_ops->apic_write(APIC_FORMAT_REG,
!                             APIC_FLAT_MODEL);
                  } else {
!                         apic_reg_ops->apic_write(APIC_FORMAT_REG,
!                             APIC_CLUSTER_MODEL);
                  }
  
!                 apic_reg_ops->apic_write(APIC_DEST_REG,
!                     AV_HIGH_ORDER >> cpun);
!         }
  
          if (apic_directed_EOI_supported()) {
                  /*
                   * Setting the 12th bit in the Spurious Interrupt Vector
                   * Register suppresses broadcast EOIs generated by the local
--- 309,330 ----
          uint_t nlvt;
          uint32_t svr = AV_UNIT_ENABLE | APIC_SPUR_INTR;
  
          apic_reg_ops->apic_write_task_reg(APIC_MASK_ALL);
  
!         ASSERT(apic_mode == LOCAL_APIC);
! 
          /*
           * We are running APIC in MMIO mode.
           */
          if (apic_flat_model) {
!                 apic_reg_ops->apic_write(APIC_FORMAT_REG, APIC_FLAT_MODEL);
          } else {
!                 apic_reg_ops->apic_write(APIC_FORMAT_REG, APIC_CLUSTER_MODEL);
          }
  
!         apic_reg_ops->apic_write(APIC_DEST_REG, AV_HIGH_ORDER >> cpun);
  
          if (apic_directed_EOI_supported()) {
                  /*
                   * Setting the 12th bit in the Spurious Interrupt Vector
                   * Register suppresses broadcast EOIs generated by the local
*** 631,694 ****
                  apic_break();
  #endif /* DEBUG */
          return (nipl);
  }
  
- /*
-  * This macro is a common code used by MMIO local apic and X2APIC
-  * local apic.
-  */
- #define APIC_INTR_EXIT() \
- { \
-         cpu_infop = &apic_cpus[psm_get_cpu_id()]; \
-         if (apic_level_intr[irq]) \
-                 apic_reg_ops->apic_send_eoi(irq); \
-         cpu_infop->aci_curipl = (uchar_t)prev_ipl; \
-         /* ISR above current pri could not be in progress */ \
-         cpu_infop->aci_ISR_in_progress &= (2 << prev_ipl) - 1; \
- }
- 
- /*
-  * Any changes made to this function must also change X2APIC
-  * version of intr_exit.
-  */
  void
  apic_intr_exit(int prev_ipl, int irq)
  {
          apic_cpus_info_t *cpu_infop;
  
          apic_reg_ops->apic_write_task_reg(apic_ipltopri[prev_ipl]);
  
!         APIC_INTR_EXIT();
  }
  
- /*
-  * Same as apic_intr_exit() except it uses MSR rather than MMIO
-  * to access local apic registers.
-  */
- void
- x2apic_intr_exit(int prev_ipl, int irq)
- {
-         apic_cpus_info_t *cpu_infop;
- 
-         X2APIC_WRITE(APIC_TASK_REG, apic_ipltopri[prev_ipl]);
-         APIC_INTR_EXIT();
- }
- 
  intr_exit_fn_t
  psm_intr_exit_fn(void)
  {
-         if (apic_mode == LOCAL_X2APIC)
-                 return (x2apic_intr_exit);
- 
          return (apic_intr_exit);
  }
  
  /*
   * Mask all interrupts below or equal to the given IPL.
-  * Any changes made to this function must also change X2APIC
-  * version of setspl.
   */
  static void
  apic_setspl(int ipl)
  {
          apic_reg_ops->apic_write_task_reg(apic_ipltopri[ipl]);
--- 627,659 ----
                  apic_break();
  #endif /* DEBUG */
          return (nipl);
  }
  
  void
  apic_intr_exit(int prev_ipl, int irq)
  {
          apic_cpus_info_t *cpu_infop;
  
          apic_reg_ops->apic_write_task_reg(apic_ipltopri[prev_ipl]);
  
!         cpu_infop = &apic_cpus[psm_get_cpu_id()];
!         if (apic_level_intr[irq])
!                 apic_reg_ops->apic_send_eoi(irq);
!         cpu_infop->aci_curipl = (uchar_t)prev_ipl;
!         /* ISR above current pri could not be in progress */
!         cpu_infop->aci_ISR_in_progress &= (2 << prev_ipl) - 1;
  }
  
  intr_exit_fn_t
  psm_intr_exit_fn(void)
  {
          return (apic_intr_exit);
  }
  
  /*
   * Mask all interrupts below or equal to the given IPL.
   */
  static void
  apic_setspl(int ipl)
  {
          apic_reg_ops->apic_write_task_reg(apic_ipltopri[ipl]);
*** 702,724 ****
           */
          if (apic_setspl_delay)
                  (void) apic_reg_ops->apic_get_pri();
  }
  
- /*
-  * X2APIC version of setspl.
-  * Mask all interrupts below or equal to the given IPL
-  */
- static void
- x2apic_setspl(int ipl)
- {
-         X2APIC_WRITE(APIC_TASK_REG, apic_ipltopri[ipl]);
- 
-         /* interrupts at ipl above this cannot be in progress */
-         apic_cpus[psm_get_cpu_id()].aci_ISR_in_progress &= (2 << ipl) - 1;
- }
- 
  /*ARGSUSED*/
  static int
  apic_addspl(int irqno, int ipl, int min_ipl, int max_ipl)
  {
          return (apic_addspl_common(irqno, ipl, min_ipl, max_ipl));
--- 667,676 ----
*** 737,781 ****
          static int cpus_started = 1;
  
          /* We know this CPU + BSP  started successfully. */
          cpus_started++;
  
-         /*
-          * On BSP we would have enabled X2APIC, if supported by processor,
-          * in acpi_probe(), but on AP we do it here.
-          *
-          * We enable X2APIC mode only if BSP is running in X2APIC & the
-          * local APIC mode of the current CPU is MMIO (xAPIC).
-          */
-         if (apic_mode == LOCAL_X2APIC && apic_detect_x2apic() &&
-             apic_local_mode() == LOCAL_APIC) {
-                 apic_enable_x2apic();
-         }
- 
-         /*
-          * Switch back to x2apic IPI sending method for performance when target
-          * CPU has entered x2apic mode.
-          */
-         if (apic_mode == LOCAL_X2APIC) {
-                 apic_switch_ipi_callback(B_FALSE);
-         }
- 
          splx(ipltospl(LOCK_LEVEL));
          apic_init_intr();
  
          /*
           * since some systems don't enable the internal cache on the non-boot
           * cpus, so we have to enable them here
           */
          setcr0(getcr0() & ~(CR0_CD | CR0_NW));
  
- #ifdef  DEBUG
          APIC_AV_PENDING_SET();
- #else
-         if (apic_mode == LOCAL_APIC)
-                 APIC_AV_PENDING_SET();
- #endif  /* DEBUG */
  
          /*
           * We may be booting, or resuming from suspend; aci_status will
           * be APIC_CPU_INTR_ENABLE if coming from suspend, so we add the
           * APIC_CPU_ONLINE flag here rather than setting aci_status completely.
--- 689,708 ----
*** 1328,1347 ****
  {
          return (apic_psm_info.p_mach_idstring);
  }
  
  void
! x2apic_update_psm(void)
  {
!         struct psm_ops *pops = &apic_ops;
  
!         ASSERT(pops != NULL);
  
!         pops->psm_intr_exit = x2apic_intr_exit;
!         pops->psm_setspl = x2apic_setspl;
  
!         pops->psm_send_ipi =  x2apic_send_ipi;
!         send_dirintf = pops->psm_send_ipi;
! 
!         apic_mode = LOCAL_X2APIC;
!         apic_change_ops();
  }
--- 1255,1281 ----
  {
          return (apic_psm_info.p_mach_idstring);
  }
  
  void
! apic_switch_ipi_callback(boolean_t enter)
  {
!         ASSERT(enter == B_TRUE);
! }
  
! int
! apic_detect_x2apic(void)
! {
!         return (0);
! }
  
! void
! apic_enable_x2apic(void)
! {
!         cmn_err(CE_PANIC, "apic_enable_x2apic() called in pcplusmp");
! }
  
! void
! x2apic_update_psm(void)
! {
!         cmn_err(CE_PANIC, "x2apic_update_psm() called in pcplusmp");
  }