plan 9 kernel history: overview | file list | diff list

1992/0630/gnot/mmu.c (diff list | history)

gnot/mmu.c on 1990/03091
1990/03091    
#include	"u.h" 
1992/0321    
#include	"../port/lib.h" 
1990/03091    
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
 
1990/06021    
struct 
{ 
	Lock; 
	int	init; 
	KMap	*free; 
1991/0821    
	KMap	arena[MB4/BY2PG];	/* kernel mmu maps up to 4MB */ 
1990/06021    
}kmapalloc; 
 
1990/03091    
/* 
 * Called splhi, not in Running state 
 */ 
void 
mapstack(Proc *p) 
{ 
	ulong tlbvirt, tlbphys; 
1990/1004    
	ulong next; 
	MMU *mm, *mn, *me; 
1990/03091    
 
1991/0705    
 
1991/0928    
	if(p->upage->va != (USERADDR|(p->pid&0xFFFF)) && p->pid != 0) 
1990/03091    
		panic("mapstack %d 0x%lux 0x%lux", p->pid, p->upage->pa, p->upage->va); 
	tlbvirt = USERADDR; 
	tlbphys = PPN(p->upage->pa) | PTEVALID | PTEKERNEL; 
	putkmmu(tlbvirt, tlbphys); 
1990/1211    
	u = (User*)USERADDR; 
1990/1004    
 
1991/0705    
	if(p->newtlb) { 
		flushmmu(); 
		p->newtlb = 0; 
	} 
 
1990/1004    
	/* 
	 *  if not a kernel process and this process was not the  
	 *  last process on this machine, flush & preload mmu 
	 */ 
	if(!p->kp && p!=m->lproc){ 
		flushmmu(); 
		m->lproc = p; 
	} 
1990/03091    
} 
 
void 
1991/0507    
mmurelease(Proc *p) 
{ 
	USED(p); 
} 
 
void 
1990/03091    
putkmmu(ulong tlbvirt, ulong tlbphys) 
{ 
	if(!(tlbvirt&KZERO)) 
		panic("putkmmu"); 
	tlbvirt &= ~KZERO; 
	KMAP[(tlbvirt&0x003FE000L)>>2] = tlbphys; 
} 
 
void 
1991/0705    
putmmu(ulong tlbvirt, ulong tlbphys, Page *p) 
1990/03091    
{ 
	if(tlbvirt&KZERO) 
		panic("putmmu"); 
	tlbphys |= VTAG(tlbvirt)<<24; 
1990/1004    
	tlbvirt = (tlbvirt&0x003FE000L)>>2; 
	UMAP[tlbvirt] = tlbphys; 
1990/03091    
} 
 
void 
flushmmu(void) 
{ 
	flushcpucache(); 
	*PARAM &= ~TLBFLUSH_; 
	*PARAM |= TLBFLUSH_; 
1990/06021    
} 
 
void 
kmapinit(void) 
{ 
1992/0625    
	int i; 
1992/0630    
	ulong endscreen; 
1992/0625    
	Page *p; 
1990/06021    
	KMap *k; 
 
	if(kmapalloc.init == 0){ 
		k = &kmapalloc.arena[0]; 
1992/0630    
		k->va = KZERO|(MB4-BY2PG); 
1990/06021    
		k->next = 0; 
		kmapalloc.free = k; 
		kmapalloc.init = 1; 
		return; 
	} 
1991/0821    
 
1992/0625    
	i = 0; 
1992/0630    
	/* 
	 * Reclaim map register for pages in bank0; 
	 * screen is in virtual space overlaying physical pages; be careful 
	 */ 
	endscreen = (PGROUND((ulong)end)&~KZERO) + 256*1024; 
1992/0625    
	for(p = palloc.head; p; p = p->next) { 
1992/0630    
		if(p->pa >= endscreen && p->pa < MB4) { 
1992/0625    
			k = &kmapalloc.arena[p->pa/BY2PG]; 
			k->va = p->pa|KZERO; 
			kunmap(k); 
			i++; 
		} 
1990/06021    
	} 
1992/0625    
	print("%lud free map registers\n", i); 
1990/06021    
} 
 
KMap* 
kmap(Page *pg) 
{ 
	KMap *k; 
1991/1004    
	int s; 
 
	s = splhi(); 
1990/06021    
	lock(&kmapalloc); 
	k = kmapalloc.free; 
1990/0709    
	if(k == 0){ 
		dumpstack(); 
1990/06021    
		panic("kmap"); 
1990/0709    
	} 
1990/06021    
	kmapalloc.free = k->next; 
	unlock(&kmapalloc); 
1991/1004    
	splx(s); 
1991/0821    
 
1990/06021    
	k->pa = pg->pa; 
	putkmmu(k->va, PPN(k->pa) | PTEVALID | PTEKERNEL); 
1991/0828    
 
1990/06021    
	return k; 
} 
 
void 
kunmap(KMap *k) 
{ 
1991/0827    
	int s; 
 
1990/06021    
	k->pa = 0; 
1991/0821    
	putkmmu(k->va, INVALIDPTE); 
 
1991/0827    
	s = splhi(); 
1990/06021    
	lock(&kmapalloc); 
	k->next = kmapalloc.free; 
	kmapalloc.free = k; 
	unlock(&kmapalloc); 
1991/0827    
	splx(s); 
1990/1211    
} 
 
void 
invalidateu(void) 
{ 
	putkmmu(USERADDR, INVALIDPTE); 
1990/03091    
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)