Changeset View
Changeset View
Standalone View
Standalone View
sys/i386/i386/mp_machdep.c
Show First 20 Lines • Show All 1,132 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Init and startup IPI. | * Init and startup IPI. | ||||
*/ | */ | ||||
void | void | ||||
ipi_startup(int apic_id, int vector) | ipi_startup(int apic_id, int vector) | ||||
{ | { | ||||
/* | /* | ||||
* This attempts to follow the algorithm described in the | |||||
* Intel Multiprocessor Specification v1.4 in section B.4. | |||||
* For each IPI, we allow the local APIC ~20us to deliver the | |||||
* IPI. If that times out, we panic. | |||||
*/ | |||||
/* | |||||
* first we do an INIT IPI: this INIT IPI might be run, resetting | * first we do an INIT IPI: this INIT IPI might be run, resetting | ||||
* and running the target CPU. OR this INIT IPI might be latched (P5 | * and running the target CPU. OR this INIT IPI might be latched (P5 | ||||
* bug), CPU waiting for STARTUP IPI. OR this INIT IPI might be | * bug), CPU waiting for STARTUP IPI. OR this INIT IPI might be | ||||
* ignored. | * ignored. | ||||
*/ | */ | ||||
lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE | | lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_LEVEL | | ||||
APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT, apic_id); | APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT, apic_id); | ||||
lapic_ipi_wait(-1); | lapic_ipi_wait(20); | ||||
/* Explicitly deassert the INIT IPI. */ | |||||
lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_LEVEL | | |||||
APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT, | |||||
apic_id); | |||||
DELAY(10000); /* wait ~10mS */ | DELAY(10000); /* wait ~10mS */ | ||||
/* | /* | ||||
* next we do a STARTUP IPI: the previous INIT IPI might still be | * next we do a STARTUP IPI: the previous INIT IPI might still be | ||||
* latched, (P5 bug) this 1st STARTUP would then terminate | * latched, (P5 bug) this 1st STARTUP would then terminate | ||||
* immediately, and the previously started INIT IPI would continue. OR | * immediately, and the previously started INIT IPI would continue. OR | ||||
* the previous INIT IPI has already run. and this STARTUP IPI will | * the previous INIT IPI has already run. and this STARTUP IPI will | ||||
* run. OR the previous INIT IPI was ignored. and this STARTUP IPI | * run. OR the previous INIT IPI was ignored. and this STARTUP IPI | ||||
* will run. | * will run. | ||||
*/ | */ | ||||
lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE | | lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE | | ||||
APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP | | APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP | | ||||
vector, apic_id); | vector, apic_id); | ||||
lapic_ipi_wait(-1); | if (!lapic_ipi_wait(20)) | ||||
panic("Failed to deliver first STARTUP IPI to APIC %d", | |||||
apic_id); | |||||
DELAY(200); /* wait ~200uS */ | DELAY(200); /* wait ~200uS */ | ||||
/* | /* | ||||
* finally we do a 2nd STARTUP IPI: this 2nd STARTUP IPI should run IF | * finally we do a 2nd STARTUP IPI: this 2nd STARTUP IPI should run IF | ||||
* the previous STARTUP IPI was cancelled by a latched INIT IPI. OR | * the previous STARTUP IPI was cancelled by a latched INIT IPI. OR | ||||
* this STARTUP IPI will be ignored, as only ONE STARTUP IPI is | * this STARTUP IPI will be ignored, as only ONE STARTUP IPI is | ||||
* recognized after hardware RESET or INIT IPI. | * recognized after hardware RESET or INIT IPI. | ||||
*/ | */ | ||||
lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE | | lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE | | ||||
APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP | | APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP | | ||||
vector, apic_id); | vector, apic_id); | ||||
lapic_ipi_wait(-1); | if (!lapic_ipi_wait(20)) | ||||
panic("Failed to deliver second STARTUP IPI to APIC %d", | |||||
apic_id); | |||||
DELAY(200); /* wait ~200uS */ | DELAY(200); /* wait ~200uS */ | ||||
} | } | ||||
/* | /* | ||||
* Send an IPI to specified CPU handling the bitmap logic. | * Send an IPI to specified CPU handling the bitmap logic. | ||||
*/ | */ | ||||
static void | static void | ||||
ipi_send_cpu(int cpu, u_int ipi) | ipi_send_cpu(int cpu, u_int ipi) | ||||
▲ Show 20 Lines • Show All 476 Lines • Show Last 20 Lines |