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>

*** 219,228 **** --- 219,231 ---- * Maximum number of vectors in a CPU that can be used for interrupt * allocation (including IPIs and the reserved vectors). */ int apix_cpu_nvectors = APIX_NVECTOR; + /* number of CPUs in power-on transition state */ + static int apic_poweron_cnt = 0; + /* gcpu.h */ extern void apic_do_interrupt(struct regs *rp, trap_trace_rec_t *ttp); extern void apic_change_eoi();
*** 2558,2567 **** --- 2561,2609 ---- vecp = apix_intx_get_vector(irqno); return (vecp); } + /* + * Switch between safe and x2APIC IPI sending method. + * The CPU may power on in xapic mode or x2apic mode. If the CPU needs to send + * an IPI to other CPUs before entering x2APIC mode, it still needs to use the + * xAPIC method. Before sending a StartIPI to the target CPU, psm_send_ipi will + * be changed to apic_common_send_ipi, which detects current local APIC mode and + * use the right method to send an IPI. If some CPUs fail to start up, + * apic_poweron_cnt won't return to zero, so apic_common_send_ipi will always be + * used. psm_send_ipi can't be simply changed back to x2apic_send_ipi if some + * CPUs failed to start up because those failed CPUs may recover itself later at + * unpredictable time. + */ + void + apic_switch_ipi_callback(boolean_t enter) + { + ulong_t iflag; + struct psm_ops *pops = psmops; + + iflag = intr_clear(); + lock_set(&apic_mode_switch_lock); + if (enter) { + ASSERT(apic_poweron_cnt >= 0); + if (apic_poweron_cnt == 0) { + pops->psm_send_ipi = apic_common_send_ipi; + send_dirintf = pops->psm_send_ipi; + } + apic_poweron_cnt++; + } else { + ASSERT(apic_poweron_cnt > 0); + apic_poweron_cnt--; + if (apic_poweron_cnt == 0) { + pops->psm_send_ipi = x2apic_send_ipi; + send_dirintf = pops->psm_send_ipi; + } + } + lock_clear(&apic_mode_switch_lock); + intr_restore(iflag); + } + /* stub function */ int apix_loaded(void) { return (apix_is_enabled);