sys/smp: Add xAPIC ICR delivery status checks to INIT-SIPI-SIPI sequence
This commit is contained in:
@@ -242,6 +242,15 @@ void lapic_write(uint32_t reg, uint32_t data) {
|
||||
mmoutd(lapic_mmio_base + reg, data);
|
||||
}
|
||||
|
||||
void lapic_icr_wait(void) {
|
||||
for (int i = 0; i < 1000000; i++) {
|
||||
if (!(lapic_read(LAPIC_REG_ICR0) & (1 << 12))) {
|
||||
return;
|
||||
}
|
||||
asm volatile ("pause");
|
||||
}
|
||||
}
|
||||
|
||||
bool x2apic_check(void) {
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
if (!cpuid(1, 0, &eax, &ebx, &ecx, &edx))
|
||||
|
||||
@@ -17,6 +17,7 @@ bool lapic_check(void);
|
||||
void lapic_eoi(void);
|
||||
uint32_t lapic_read(uint32_t reg);
|
||||
void lapic_write(uint32_t reg, uint32_t data);
|
||||
void lapic_icr_wait(void);
|
||||
|
||||
bool x2apic_check(void);
|
||||
bool x2apic_enable(void);
|
||||
|
||||
@@ -84,6 +84,7 @@ static bool smp_start_ap(uint32_t lapic_id, struct gdtr *gdtr,
|
||||
if (x2apic) {
|
||||
x2apic_write(LAPIC_REG_ICR0, ((uint64_t)lapic_id << 32) | 0x4500);
|
||||
} else {
|
||||
lapic_icr_wait();
|
||||
lapic_write(LAPIC_REG_ICR1, lapic_id << 24);
|
||||
lapic_write(LAPIC_REG_ICR0, 0x4500);
|
||||
}
|
||||
@@ -95,10 +96,17 @@ static bool smp_start_ap(uint32_t lapic_id, struct gdtr *gdtr,
|
||||
x2apic_write(LAPIC_REG_ICR0, ((uint64_t)lapic_id << 32) |
|
||||
((size_t)trampoline / 4096) | 0x4600);
|
||||
} else {
|
||||
lapic_icr_wait();
|
||||
lapic_write(LAPIC_REG_ICR1, lapic_id << 24);
|
||||
lapic_write(LAPIC_REG_ICR0, ((size_t)trampoline / 4096) | 0x4600);
|
||||
}
|
||||
stall(200);
|
||||
if (j == 0) {
|
||||
stall(200);
|
||||
}
|
||||
}
|
||||
|
||||
if (!x2apic) {
|
||||
lapic_icr_wait();
|
||||
}
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
|
||||
Reference in New Issue
Block a user