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"); }