提交 0a6a7f01 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

Call lapicwait and used recommended delays in lapicstartap (it makes a difference on tom).

上级 5077b524
...@@ -55,14 +55,14 @@ lapicr(u32 off) ...@@ -55,14 +55,14 @@ lapicr(u32 off)
} }
static int static int
apic_icr_wait() lapicwait()
{ {
int i = 100000; int i = 100000;
while ((lapicr(ICRLO) & BUSY) != 0) { while ((lapicr(ICRLO) & BUSY) != 0) {
nop_pause(); nop_pause();
i--; i--;
if (i == 0) { if (i == 0) {
cprintf("apic_icr_wait: wedged?\n"); cprintf("lapicwait: wedged?\n");
return -1; return -1;
} }
} }
...@@ -149,8 +149,8 @@ lapic_ipi(int cpu, int ino) ...@@ -149,8 +149,8 @@ lapic_ipi(int cpu, int ino)
{ {
lapicw(ICRHI, cpu << 24); lapicw(ICRHI, cpu << 24);
lapicw(ICRLO, FIXED | DEASSERT | ino); lapicw(ICRLO, FIXED | DEASSERT | ino);
if (apic_icr_wait() < 0) if (lapicwait() < 0)
panic("lapic_ipi: icr_wait failure"); panic("lapic_ipi: lapicwait failure");
} }
void void
...@@ -182,9 +182,11 @@ lapicstartap(u8 apicid, u32 addr) ...@@ -182,9 +182,11 @@ lapicstartap(u8 apicid, u32 addr)
// Send INIT (level-triggered) interrupt to reset other CPU. // Send INIT (level-triggered) interrupt to reset other CPU.
lapicw(ICRHI, apicid<<24); lapicw(ICRHI, apicid<<24);
lapicw(ICRLO, apicid | INIT | LEVEL | ASSERT); lapicw(ICRLO, apicid | INIT | LEVEL | ASSERT);
microdelay(200); lapicwait();
microdelay(10000);
lapicw(ICRLO, apicid |INIT | LEVEL); lapicw(ICRLO, apicid |INIT | LEVEL);
microdelay(100); // should be 10ms, but too slow in Bochs! lapicwait();
microdelay(10000); // should be 10ms, but too slow in Bochs!
// Send startup IPI (twice!) to enter bootstrap code. // Send startup IPI (twice!) to enter bootstrap code.
// Regular hardware is supposed to only accept a STARTUP // Regular hardware is supposed to only accept a STARTUP
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论