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