提交 39b1cf6b 创建 作者: Nickolai Zeldovich's avatar Nickolai Zeldovich

bring back tlb shootdown code

上级 41fc9e5e
...@@ -79,6 +79,7 @@ int cpunum(void); ...@@ -79,6 +79,7 @@ int cpunum(void);
extern volatile uint* lapic; extern volatile uint* lapic;
void lapiceoi(void); void lapiceoi(void);
void lapicinit(int); void lapicinit(int);
void lapic_tlbflush(uint);
void lapicstartap(uchar, uint); void lapicstartap(uchar, uint);
void microdelay(int); void microdelay(int);
......
...@@ -47,6 +47,27 @@ lapicw(int index, int value) ...@@ -47,6 +47,27 @@ lapicw(int index, int value)
lapic[ID]; // wait for write to finish, by reading lapic[ID]; // wait for write to finish, by reading
} }
static uint
lapicr(uint off)
{
return lapic[off];
}
static int
apic_icr_wait()
{
uint i = 100000;
while ((lapicr(ICRLO) & BUSY) != 0) {
nop_pause();
i--;
if (i == 0) {
cprintf("apic_icr_wait: wedged?\n");
return -1;
}
}
return 0;
}
//PAGEBREAK! //PAGEBREAK!
void void
lapicinit(int c) lapicinit(int c)
...@@ -130,6 +151,22 @@ microdelay(int us) ...@@ -130,6 +151,22 @@ microdelay(int us)
{ {
} }
// Send IPI
void
lapic_ipi(int cpu, int ino)
{
lapicw(ICRHI, cpu << 24);
lapicw(ICRLO, FIXED | DEASSERT | ino);
if (apic_icr_wait() < 0)
panic("lapic_ipi: icr_wait failure");
}
void
lapic_tlbflush(uint cpu)
{
lapic_ipi(cpu, T_TLBFLUSH);
}
#define IO_RTC 0x70 #define IO_RTC 0x70
// Start additional processor running bootstrap code at addr. // Start additional processor running bootstrap code at addr.
......
...@@ -134,7 +134,12 @@ sys_unmap(void) ...@@ -134,7 +134,12 @@ sys_unmap(void)
clearpages(proc->pgdir, clearpages(proc->pgdir,
(void*) (PGROUNDDOWN(addr)), (void*) (PGROUNDDOWN(addr)),
(void*) (PGROUNDDOWN(addr)+PGROUNDUP(len))); (void*) (PGROUNDDOWN(addr)+PGROUNDUP(len)));
cli();
lcr3(PADDR(proc->pgdir)); lcr3(PADDR(proc->pgdir));
for (uint i = 0; i < ncpu; i++)
if (i != cpu->id)
lapic_tlbflush(i);
sti();
return 0; return 0;
} }
......
...@@ -79,6 +79,9 @@ trap(struct trapframe *tf) ...@@ -79,6 +79,9 @@ trap(struct trapframe *tf)
cprintf("cpu%d: spurious interrupt at %x:%x\n", cprintf("cpu%d: spurious interrupt at %x:%x\n",
cpu->id, tf->cs, tf->eip); cpu->id, tf->cs, tf->eip);
lapiceoi(); lapiceoi();
case T_TLBFLUSH:
lapiceoi();
lcr3(rcr3());
break; break;
//PAGEBREAK: 13 //PAGEBREAK: 13
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
// These are arbitrarily chosen, but with care not to overlap // These are arbitrarily chosen, but with care not to overlap
// processor defined exceptions or interrupt vectors. // processor defined exceptions or interrupt vectors.
#define T_SYSCALL 64 // system call #define T_SYSCALL 64 // system call
#define T_TLBFLUSH 65 // flush TLB
#define T_DEFAULT 500 // catchall #define T_DEFAULT 500 // catchall
#define T_IRQ0 32 // IRQ 0 corresponds to int T_IRQ #define T_IRQ0 32 // IRQ 0 corresponds to int T_IRQ
......
...@@ -138,6 +138,12 @@ xchg(volatile uint *addr, uint newval) ...@@ -138,6 +138,12 @@ xchg(volatile uint *addr, uint newval)
return result; return result;
} }
static inline void
nop_pause(void)
{
__asm volatile("pause" : :);
}
//PAGEBREAK! //PAGEBREAK!
static inline void static inline void
lcr0(uint val) lcr0(uint val)
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论