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/pcplusmp/apic.c
          +++ new/usr/src/uts/i86pc/io/pcplusmp/apic.c
↓ open down ↓ 92 lines elided ↑ open up ↑
  93   93  /*
  94   94   *      standard MP entries
  95   95   */
  96   96  static int      apic_probe(void);
  97   97  static int      apic_getclkirq(int ipl);
  98   98  static void     apic_init(void);
  99   99  static void     apic_picinit(void);
 100  100  static int      apic_post_cpu_start(void);
 101  101  static int      apic_intr_enter(int ipl, int *vect);
 102  102  static void     apic_setspl(int ipl);
 103      -static void     x2apic_setspl(int ipl);
 104  103  static int      apic_addspl(int ipl, int vector, int min_ipl, int max_ipl);
 105  104  static int      apic_delspl(int ipl, int vector, int min_ipl, int max_ipl);
 106  105  static int      apic_disable_intr(processorid_t cpun);
 107  106  static void     apic_enable_intr(processorid_t cpun);
 108  107  static int              apic_get_ipivect(int ipl, int type);
 109  108  static void     apic_post_cyclic_setup(void *arg);
 110  109  
 111  110  /*
 112  111   * The following vector assignments influence the value of ipltopri and
 113  112   * vectortoipl. Note that vectors 0 - 0x1f are not used. We can program
↓ open down ↓ 191 lines elided ↑ open up ↑
 305  304  
 306  305  static void
 307  306  apic_init_intr(void)
 308  307  {
 309  308          processorid_t   cpun = psm_get_cpu_id();
 310  309          uint_t nlvt;
 311  310          uint32_t svr = AV_UNIT_ENABLE | APIC_SPUR_INTR;
 312  311  
 313  312          apic_reg_ops->apic_write_task_reg(APIC_MASK_ALL);
 314  313  
 315      -        if (apic_mode == LOCAL_APIC) {
 316      -                /*
 317      -                 * We are running APIC in MMIO mode.
 318      -                 */
 319      -                if (apic_flat_model) {
 320      -                        apic_reg_ops->apic_write(APIC_FORMAT_REG,
 321      -                            APIC_FLAT_MODEL);
 322      -                } else {
 323      -                        apic_reg_ops->apic_write(APIC_FORMAT_REG,
 324      -                            APIC_CLUSTER_MODEL);
 325      -                }
      314 +        ASSERT(apic_mode == LOCAL_APIC);
 326  315  
 327      -                apic_reg_ops->apic_write(APIC_DEST_REG,
 328      -                    AV_HIGH_ORDER >> cpun);
      316 +        /*
      317 +         * We are running APIC in MMIO mode.
      318 +         */
      319 +        if (apic_flat_model) {
      320 +                apic_reg_ops->apic_write(APIC_FORMAT_REG, APIC_FLAT_MODEL);
      321 +        } else {
      322 +                apic_reg_ops->apic_write(APIC_FORMAT_REG, APIC_CLUSTER_MODEL);
 329  323          }
 330  324  
      325 +        apic_reg_ops->apic_write(APIC_DEST_REG, AV_HIGH_ORDER >> cpun);
      326 +
 331  327          if (apic_directed_EOI_supported()) {
 332  328                  /*
 333  329                   * Setting the 12th bit in the Spurious Interrupt Vector
 334  330                   * Register suppresses broadcast EOIs generated by the local
 335  331                   * APIC. The suppression of broadcast EOIs happens only when
 336  332                   * interrupts are level-triggered.
 337  333                   */
 338  334                  svr |= APIC_SVR_SUPPRESS_BROADCAST_EOI;
 339  335          }
 340  336  
↓ open down ↓ 285 lines elided ↑ open up ↑
 626  622          APIC_DEBUG_BUF_PUT(psm_get_cpu_id());
 627  623          if ((apic_stretch_interrupts) && (apic_stretch_ISR & (1 << nipl)))
 628  624                  drv_usecwait(apic_stretch_interrupts);
 629  625  
 630  626          if (apic_break_on_cpu == psm_get_cpu_id())
 631  627                  apic_break();
 632  628  #endif /* DEBUG */
 633  629          return (nipl);
 634  630  }
 635  631  
 636      -/*
 637      - * This macro is a common code used by MMIO local apic and X2APIC
 638      - * local apic.
 639      - */
 640      -#define APIC_INTR_EXIT() \
 641      -{ \
 642      -        cpu_infop = &apic_cpus[psm_get_cpu_id()]; \
 643      -        if (apic_level_intr[irq]) \
 644      -                apic_reg_ops->apic_send_eoi(irq); \
 645      -        cpu_infop->aci_curipl = (uchar_t)prev_ipl; \
 646      -        /* ISR above current pri could not be in progress */ \
 647      -        cpu_infop->aci_ISR_in_progress &= (2 << prev_ipl) - 1; \
 648      -}
 649      -
 650      -/*
 651      - * Any changes made to this function must also change X2APIC
 652      - * version of intr_exit.
 653      - */
 654  632  void
 655  633  apic_intr_exit(int prev_ipl, int irq)
 656  634  {
 657  635          apic_cpus_info_t *cpu_infop;
 658  636  
 659  637          apic_reg_ops->apic_write_task_reg(apic_ipltopri[prev_ipl]);
 660  638  
 661      -        APIC_INTR_EXIT();
      639 +        cpu_infop = &apic_cpus[psm_get_cpu_id()];
      640 +        if (apic_level_intr[irq])
      641 +                apic_reg_ops->apic_send_eoi(irq);
      642 +        cpu_infop->aci_curipl = (uchar_t)prev_ipl;
      643 +        /* ISR above current pri could not be in progress */
      644 +        cpu_infop->aci_ISR_in_progress &= (2 << prev_ipl) - 1;
 662  645  }
 663  646  
 664      -/*
 665      - * Same as apic_intr_exit() except it uses MSR rather than MMIO
 666      - * to access local apic registers.
 667      - */
 668      -void
 669      -x2apic_intr_exit(int prev_ipl, int irq)
 670      -{
 671      -        apic_cpus_info_t *cpu_infop;
 672      -
 673      -        X2APIC_WRITE(APIC_TASK_REG, apic_ipltopri[prev_ipl]);
 674      -        APIC_INTR_EXIT();
 675      -}
 676      -
 677  647  intr_exit_fn_t
 678  648  psm_intr_exit_fn(void)
 679  649  {
 680      -        if (apic_mode == LOCAL_X2APIC)
 681      -                return (x2apic_intr_exit);
 682      -
 683  650          return (apic_intr_exit);
 684  651  }
 685  652  
 686  653  /*
 687  654   * Mask all interrupts below or equal to the given IPL.
 688      - * Any changes made to this function must also change X2APIC
 689      - * version of setspl.
 690  655   */
 691  656  static void
 692  657  apic_setspl(int ipl)
 693  658  {
 694  659          apic_reg_ops->apic_write_task_reg(apic_ipltopri[ipl]);
 695  660  
 696  661          /* interrupts at ipl above this cannot be in progress */
 697  662          apic_cpus[psm_get_cpu_id()].aci_ISR_in_progress &= (2 << ipl) - 1;
 698  663          /*
 699  664           * this is a patch fix for the ALR QSMP P5 machine, so that interrupts
 700  665           * have enough time to come in before the priority is raised again
 701  666           * during the idle() loop.
 702  667           */
 703  668          if (apic_setspl_delay)
 704  669                  (void) apic_reg_ops->apic_get_pri();
 705  670  }
 706  671  
 707      -/*
 708      - * X2APIC version of setspl.
 709      - * Mask all interrupts below or equal to the given IPL
 710      - */
 711      -static void
 712      -x2apic_setspl(int ipl)
 713      -{
 714      -        X2APIC_WRITE(APIC_TASK_REG, apic_ipltopri[ipl]);
 715      -
 716      -        /* interrupts at ipl above this cannot be in progress */
 717      -        apic_cpus[psm_get_cpu_id()].aci_ISR_in_progress &= (2 << ipl) - 1;
 718      -}
 719      -
 720  672  /*ARGSUSED*/
 721  673  static int
 722  674  apic_addspl(int irqno, int ipl, int min_ipl, int max_ipl)
 723  675  {
 724  676          return (apic_addspl_common(irqno, ipl, min_ipl, max_ipl));
 725  677  }
 726  678  
 727  679  static int
 728  680  apic_delspl(int irqno, int ipl, int min_ipl, int max_ipl)
 729  681  {
↓ open down ↓ 2 lines elided ↑ open up ↑
 732  684  
 733  685  static int
 734  686  apic_post_cpu_start(void)
 735  687  {
 736  688          int cpun;
 737  689          static int cpus_started = 1;
 738  690  
 739  691          /* We know this CPU + BSP  started successfully. */
 740  692          cpus_started++;
 741  693  
 742      -        /*
 743      -         * On BSP we would have enabled X2APIC, if supported by processor,
 744      -         * in acpi_probe(), but on AP we do it here.
 745      -         *
 746      -         * We enable X2APIC mode only if BSP is running in X2APIC & the
 747      -         * local APIC mode of the current CPU is MMIO (xAPIC).
 748      -         */
 749      -        if (apic_mode == LOCAL_X2APIC && apic_detect_x2apic() &&
 750      -            apic_local_mode() == LOCAL_APIC) {
 751      -                apic_enable_x2apic();
 752      -        }
 753      -
 754      -        /*
 755      -         * Switch back to x2apic IPI sending method for performance when target
 756      -         * CPU has entered x2apic mode.
 757      -         */
 758      -        if (apic_mode == LOCAL_X2APIC) {
 759      -                apic_switch_ipi_callback(B_FALSE);
 760      -        }
 761      -
 762  694          splx(ipltospl(LOCK_LEVEL));
 763  695          apic_init_intr();
 764  696  
 765  697          /*
 766  698           * since some systems don't enable the internal cache on the non-boot
 767  699           * cpus, so we have to enable them here
 768  700           */
 769  701          setcr0(getcr0() & ~(CR0_CD | CR0_NW));
 770  702  
 771      -#ifdef  DEBUG
 772  703          APIC_AV_PENDING_SET();
 773      -#else
 774      -        if (apic_mode == LOCAL_APIC)
 775      -                APIC_AV_PENDING_SET();
 776      -#endif  /* DEBUG */
 777  704  
 778  705          /*
 779  706           * We may be booting, or resuming from suspend; aci_status will
 780  707           * be APIC_CPU_INTR_ENABLE if coming from suspend, so we add the
 781  708           * APIC_CPU_ONLINE flag here rather than setting aci_status completely.
 782  709           */
 783  710          cpun = psm_get_cpu_id();
 784  711          apic_cpus[cpun].aci_status |= APIC_CPU_ONLINE;
 785  712  
 786  713          apic_reg_ops->apic_write(APIC_DIVIDE_REG, apic_divide_reg_init);
↓ open down ↓ 536 lines elided ↑ open up ↑
1323 1250          return (vector);
1324 1251  }
1325 1252  
1326 1253  char *
1327 1254  apic_get_apic_type(void)
1328 1255  {
1329 1256          return (apic_psm_info.p_mach_idstring);
1330 1257  }
1331 1258  
1332 1259  void
1333      -x2apic_update_psm(void)
     1260 +apic_switch_ipi_callback(boolean_t enter)
1334 1261  {
1335      -        struct psm_ops *pops = &apic_ops;
     1262 +        ASSERT(enter == B_TRUE);
     1263 +}
1336 1264  
1337      -        ASSERT(pops != NULL);
     1265 +int
     1266 +apic_detect_x2apic(void)
     1267 +{
     1268 +        return (0);
     1269 +}
1338 1270  
1339      -        pops->psm_intr_exit = x2apic_intr_exit;
1340      -        pops->psm_setspl = x2apic_setspl;
     1271 +void
     1272 +apic_enable_x2apic(void)
     1273 +{
     1274 +        cmn_err(CE_PANIC, "apic_enable_x2apic() called in pcplusmp");
     1275 +}
1341 1276  
1342      -        pops->psm_send_ipi =  x2apic_send_ipi;
1343      -        send_dirintf = pops->psm_send_ipi;
1344      -
1345      -        apic_mode = LOCAL_X2APIC;
1346      -        apic_change_ops();
     1277 +void
     1278 +x2apic_update_psm(void)
     1279 +{
     1280 +        cmn_err(CE_PANIC, "x2apic_update_psm() called in pcplusmp");
1347 1281  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX