Ejemplo n.º 1
0
/* Needs to be called during startup.  It records the state the BIOS
 * leaves the local APIC so we can undo upon kexec.
 */
void __init record_boot_APIC_mode(void)
{
    /* Sanity check - we should only ever run once, but could possibly
     * be called several times */
    if ( APIC_MODE_INVALID != apic_boot_mode )
        return;

    apic_boot_mode = current_local_apic_mode();

    apic_printk(APIC_DEBUG, "APIC boot state is '%s'\n",
                apic_mode_to_str(apic_boot_mode));
}
Ejemplo n.º 2
0
Archivo: apic.c Proyecto: robhoes/xen
void disable_local_APIC(void)
{
    clear_local_APIC();

    /*
     * Disable APIC (implies clearing of registers
     * for 82489DX!).
     */
    apic_write_around(APIC_SPIV,
        apic_read(APIC_SPIV) & ~APIC_SPIV_APIC_ENABLED);

    if (enabled_via_apicbase) {
        uint64_t msr_content;
        rdmsrl(MSR_IA32_APICBASE, msr_content);
        wrmsrl(MSR_IA32_APICBASE, msr_content &
               ~(MSR_IA32_APICBASE_ENABLE|MSR_IA32_APICBASE_EXTD));
    }

    if ( kexecing && (current_local_apic_mode() != apic_boot_mode) )
    {
        uint64_t msr_content;
        rdmsrl(MSR_IA32_APICBASE, msr_content);
        msr_content &= ~(MSR_IA32_APICBASE_ENABLE|MSR_IA32_APICBASE_EXTD);
        wrmsrl(MSR_IA32_APICBASE, msr_content);

        switch ( apic_boot_mode )
        {
        case APIC_MODE_DISABLED:
            break; /* Nothing to do - we did this above */
        case APIC_MODE_XAPIC:
            msr_content |= MSR_IA32_APICBASE_ENABLE;
            wrmsrl(MSR_IA32_APICBASE, msr_content);
            break;
        case APIC_MODE_X2APIC:
            msr_content |= MSR_IA32_APICBASE_ENABLE;
            wrmsrl(MSR_IA32_APICBASE, msr_content);
            msr_content |= MSR_IA32_APICBASE_EXTD;
            wrmsrl(MSR_IA32_APICBASE, msr_content);
            break;
        default:
            printk("Default case when reverting #%d lapic to boot state\n",
                   smp_processor_id());
            break;
        }
    }

}
Ejemplo n.º 3
0
static void nmi_shootdown_cpus(void)
{
    unsigned long msecs;

    local_irq_disable();

    if ( hpet_broadcast_is_available() )
        hpet_disable_legacy_broadcast();

    crashing_cpu = smp_processor_id();
    local_irq_count(crashing_cpu) = 0;

    atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
    /* Would it be better to replace the trap vector here? */
    set_nmi_callback(crash_nmi_callback);
    /* Ensure the new callback function is set before sending out the NMI. */
    wmb();

    smp_send_nmi_allbutself();

    msecs = 1000; /* Wait at most a second for the other cpus to stop */
    while ( (atomic_read(&waiting_for_crash_ipi) > 0) && msecs )
    {
        mdelay(1);
        msecs--;
    }

    /* Crash shutdown any IOMMU functionality as the crashdump kernel is not
     * happy when booting if interrupt/dma remapping is still enabled */
    iommu_crash_shutdown();

    __stop_this_cpu();

    /* This is a bit of a hack due to the problems with the x2apic_enabled
     * variable, but we can't do any better without a significant refactoring
     * of the APIC code */
    x2apic_enabled = (current_local_apic_mode() == APIC_MODE_X2APIC);

    disable_IO_APIC();
    hpet_disable();
}