static uvlong origlvl1; /* physical address */
static uvlong klvl2; /* physical, as created by boot loader */
static uchar *nextio; /* next virtual address to be allocated by kmapv */
extern Bootconf *bootconf;
/* set PCB to new one in mach structure before stomping on old one */
m->usp = 0;
m->fen = 1;
m->ptbr = bootconf->pcb->ptbr;
origlvl1 = (m->ptbr << PGSHIFT);
setpcb(m);
/*
* Called splhi, not in Running state
*/
void
mmuswitch(Proc *p)
{
Page *pg;
uvlong *lvl2;
if(p->newtlb){
/*
* newtlb set means that they are inconsistent
* with the segment.c data structures.
*
* bin the current 3rd level page tables and
* the pointers to them in the 2nd level page.
* pg->daddr is used by putmmu to save the offset into
* the 2nd level page.
*/
if(p->mmutop && p->mmuused){
lvl2 = (uvlong*)p->mmulvl2->va;
for(pg = p->mmuused; pg->next; pg = pg->next)
lvl2[pg->daddr] = 0;
lvl2[pg->daddr] = 0;
pg->next = p->mmufree;
p->mmufree = p->mmuused;
p->mmuused = 0;
}
p->newtlb = 0;
}
/* tell processor about new page table and flush cached entries */
if(p->mmutop == 0)
setptb(origlvl1);
else
setptb(p->mmutop->pa);
tlbflush(-1, 0);
icflush();
}
/*
* give all page table pages back to the free pool. This is called in sched()
* with palloc locked.
*/
void
mmurelease(Proc *p)
{
Page *pg;
Page *next;
if(canlock(&palloc))
panic("mmurelease");
/* point to protoype page map */
setptb(origlvl1);
icflush();