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

1993/0812/power/mmu.c (diff list | history)

1990/0227/sys/src/9/power/mmu.c:101,1031990/1211/sys/src/9/power/mmu.c:101,114 (short | long)
1990/0227    
	mapstack(u->p); 
	spllo(); 
} 
1990/1211    
 
void 
clearmmucache(void) 
{ 
} 
 
void 
invalidateu(void) 
{ 
	puttlbx(0, KZERO | PTEPID(0), 0); 
} 
1990/1211/sys/src/9/power/mmu.c:25,301991/0425/sys/src/9/power/mmu.c:25,31 (short | long)
1990/0227    
	tlbvirt = USERADDR | PTEPID(tp); 
	tlbphys = p->upage->pa | PTEWRITE | PTEVALID | PTEGLOBL; 
	puttlbx(0, tlbvirt, tlbphys); 
1991/0425    
	putstlb(tlbvirt, tlbphys); 
1990/0227    
	u = (User*)USERADDR; 
} 
 
1990/1211/sys/src/9/power/mmu.c:34,521991/0425/sys/src/9/power/mmu.c:35,78
1990/0227    
int 
newtlbpid(Proc *p) 
{ 
	int i; 
1991/0425    
	int i, s; 
1990/0227    
	Proc *sp; 
                 
1991/0425    
	char *h; 
/* 
	s = m->lastpid; 
	if(s >= NTLBPID) 
		s = 1; 
	i = s; 
	h = m->pidhere; 
	do{ 
		i++; 
		if(i >= NTLBPID) 
			i = 1; 
	}while(h[i] && i != s); 
	 
	if(i == s){ 
		sp = m->pidproc[i]; 
		if(sp){ 
			if(sp->pidonmach[m->machno] == i) 
				sp->pidonmach[m->machno] = 0; 
			purgetlb(i); 
		} 
	} 
*/ 
1990/0227    
	i = m->lastpid+1; 
	if(i >= NTLBPID) 
		i = 1; 
	sp = m->pidproc[i]; 
	if(sp){ 
1991/0425    
		if(sp->pidonmach[m->machno] == i) 
			sp->pidonmach[m->machno] = 0; 
 
1990/0227    
		sp->pidonmach[m->machno] = 0; 
		purgetlb(i); 
	} 
	m->pidproc[i] = p; 
1991/0425    
 
1990/0227    
	m->lastpid = i; 
1991/0425    
	m->pidproc[i] = p; 
1990/0227    
	return i; 
} 
 
1990/1211/sys/src/9/power/mmu.c:68,731991/0425/sys/src/9/power/mmu.c:94,100
1990/0227    
		p->pidonmach[m->machno] = tp; 
	} 
	tlbvirt |= PTEPID(tp); 
1991/0425    
	putstlb(tlbvirt, tlbphys); 
1990/0227    
	puttlb(tlbvirt, tlbphys); 
	m->pidhere[tp] = 1; 
	p->state = Running; 
1990/1211/sys/src/9/power/mmu.c:77,941991/0425/sys/src/9/power/mmu.c:104,141
1990/0227    
void 
purgetlb(int pid) 
{ 
1991/0425    
	Softtlb *entry, *etab; 
	char p[NTLBPID]; 
	Proc *sp; 
1990/0227    
	int i, rpid; 
 
	if(m->pidhere[pid] == 0) 
1991/0425    
	if(m->pidproc[pid] == 0) 
1990/0227    
		return; 
	memset(m->pidhere, 0, sizeof m->pidhere); 
	for(i=TLBROFF; i<NTLB; i++){ 
		rpid = (gettlbvirt(i)>>6) & 0x3F; 
		if(rpid == pid) 
1991/0425    
 
	m->tlbpurge++; 
	m->pidproc[pid] = 0; 
	memset(p, 0, sizeof p); 
	for(i=TLBROFF; i<NTLB; i++) 
		if(TLBPID(gettlbvirt(i)) == pid) 
1990/0227    
			puttlbx(i, KZERO | PTEPID(i), 0); 
		else 
			m->pidhere[rpid] = 1; 
1991/0425    
	entry = m->stb; 
	etab = &entry[STLBSIZE]; 
	for(; entry < etab; entry++){ 
		rpid = TLBPID(entry->virt); 
		if(rpid == pid){ 
			entry->phys = 0; 
			entry->virt = 0; 
		}else 
			p[rpid] = 1; 
1990/0227    
	} 
1991/0425    
	for(i = 0; i < NTLBPID; i++) 
		if(p[i] == 0){ 
			sp = m->pidproc[i]; 
			if(sp && sp->pidonmach[m->machno] == i) 
				sp->pidonmach[m->machno] = 0; 
			m->pidproc[i] = 0; 
			m->pidhere[i] = 0; 
		} 
1990/0227    
} 
 
void 
1990/1211/sys/src/9/power/mmu.c:111,1141991/0425/sys/src/9/power/mmu.c:158,174
1990/1211    
invalidateu(void) 
{ 
	puttlbx(0, KZERO | PTEPID(0), 0); 
1991/0425    
	putstlb(KZERO | PTEPID(0), 0); 
} 
 
void 
putstlb(ulong tlbvirt, ulong tlbphys) 
{ 
	Softtlb *entry; 
 
	entry = &m->stb[((tlbvirt<<1) ^ (tlbvirt>>12)) & (STLBSIZE-1)]; 
	entry->phys = tlbphys; 
	entry->virt = tlbvirt; 
	if(tlbphys == 0) 
		entry->virt = 0; 
1990/1211    
} 
1991/0425/sys/src/9/power/mmu.c:38,441991/0426/sys/src/9/power/mmu.c:38,44 (short | long)
1991/0425    
	int i, s; 
1990/0227    
	Proc *sp; 
1991/0425    
	char *h; 
/* 
1991/0426    
 
1991/0425    
	s = m->lastpid; 
	if(s >= NTLBPID) 
		s = 1; 
1991/0425/sys/src/9/power/mmu.c:51,761991/0426/sys/src/9/power/mmu.c:51,66
1991/0425    
	}while(h[i] && i != s); 
	 
	if(i == s){ 
		sp = m->pidproc[i]; 
		if(sp){ 
			if(sp->pidonmach[m->machno] == i) 
				sp->pidonmach[m->machno] = 0; 
			purgetlb(i); 
		} 
1991/0426    
		i++; 
		if(i >= NTLBPID) 
			i = 1; 
1991/0425    
	} 
*/ 
1990/0227    
	i = m->lastpid+1; 
	if(i >= NTLBPID) 
		i = 1; 
	sp = m->pidproc[i]; 
	if(sp){ 
1991/0425    
		if(sp->pidonmach[m->machno] == i) 
			sp->pidonmach[m->machno] = 0; 
                 
1990/0227    
		sp->pidonmach[m->machno] = 0; 
		purgetlb(i); 
	} 
1991/0425    
                 
1990/0227    
	m->lastpid = i; 
1991/0425    
	m->pidproc[i] = p; 
1990/0227    
	return i; 
1991/0425/sys/src/9/power/mmu.c:105,1201991/0426/sys/src/9/power/mmu.c:95,110
1990/0227    
purgetlb(int pid) 
{ 
1991/0425    
	Softtlb *entry, *etab; 
	char p[NTLBPID]; 
1991/0426    
	char *p; 
1991/0425    
	Proc *sp; 
1990/0227    
	int i, rpid; 
 
1991/0425    
	if(m->pidproc[pid] == 0) 
1991/0426    
	if(m->pidhere[pid] == 0) 
1990/0227    
		return; 
1991/0425    
 
	m->tlbpurge++; 
	m->pidproc[pid] = 0; 
	memset(p, 0, sizeof p); 
1991/0426    
	p = m->pidhere; 
	memset(m->pidhere, 0, sizeof m->pidhere); 
1991/0425    
	for(i=TLBROFF; i<NTLB; i++) 
		if(TLBPID(gettlbvirt(i)) == pid) 
1990/0227    
			puttlbx(i, KZERO | PTEPID(i), 0); 
1991/0425/sys/src/9/power/mmu.c:128,1411991/0426/sys/src/9/power/mmu.c:118,123
1991/0425    
		}else 
			p[rpid] = 1; 
1990/0227    
	} 
1991/0425    
	for(i = 0; i < NTLBPID; i++) 
		if(p[i] == 0){ 
			sp = m->pidproc[i]; 
			if(sp && sp->pidonmach[m->machno] == i) 
				sp->pidonmach[m->machno] = 0; 
			m->pidproc[i] = 0; 
			m->pidhere[i] = 0; 
		} 
1990/0227    
} 
 
void 
1991/0426/sys/src/9/power/mmu.c:14,311991/0430/sys/src/9/power/mmu.c:14,28 (short | long)
1990/0227    
	ulong tlbvirt, tlbphys; 
 
	tp = p->pidonmach[m->machno]; 
	if(tp == 0){ 
1991/0430    
	if(tp == 0) 
1990/0227    
		tp = newtlbpid(p); 
		p->pidonmach[m->machno] = tp; 
	} 
/*	if(p->upage->va != (USERADDR|(p->pid&0xFFFF))) 
		panic("mapstack %d 0x%lux 0x%lux", p->pid, p->upage->pa, p->upage->va); 
*/ 
	/* don't set m->pidhere[*tp] because we're only writing entry 0 */ 
1991/0430    
	/* don't set m->pidhere[tp] because we're only writing entry 0 */ 
1990/0227    
	tlbvirt = USERADDR | PTEPID(tp); 
	tlbphys = p->upage->pa | PTEWRITE | PTEVALID | PTEGLOBL; 
	puttlbx(0, tlbvirt, tlbphys); 
1991/0425    
	putstlb(tlbvirt, tlbphys); 
1990/0227    
	u = (User*)USERADDR; 
} 
 
1991/0426/sys/src/9/power/mmu.c:43,541991/0430/sys/src/9/power/mmu.c:40,47
1991/0425    
	if(s >= NTLBPID) 
		s = 1; 
	i = s; 
	h = m->pidhere; 
	do{ 
		i++; 
		if(i >= NTLBPID) 
			i = 1; 
	}while(h[i] && i != s); 
1991/0430    
	for(h = m->pidhere; h[i] && i != s; i = (i == NTLBPID - 1 ? 1 : i + 1)) 
		; 
1991/0425    
	 
	if(i == s){ 
1991/0426    
		i++; 
1991/0426/sys/src/9/power/mmu.c:55,681991/0430/sys/src/9/power/mmu.c:48,64
1991/0426    
		if(i >= NTLBPID) 
			i = 1; 
1991/0425    
	} 
1991/0430    
	 
1990/0227    
	sp = m->pidproc[i]; 
1991/0430    
	m->lastpid = i; 
	m->pidproc[i] = p; 
	p->pidonmach[m->machno] = i; 
1990/0227    
	if(sp){ 
1991/0425    
		if(sp->pidonmach[m->machno] == i) 
			sp->pidonmach[m->machno] = 0; 
1990/0227    
		purgetlb(i); 
1991/0430    
		if(h[i]) 
			purgetlb(i); 
1990/0227    
	} 
	m->lastpid = i; 
1991/0425    
	m->pidproc[i] = p; 
1990/0227    
	return i; 
} 
 
1991/0426/sys/src/9/power/mmu.c:79,881991/0430/sys/src/9/power/mmu.c:75,82
1990/0227    
*/ 
	p->state = MMUing; 
	tp = p->pidonmach[m->machno]; 
	if(tp == 0){ 
1991/0430    
	if(tp == 0) 
1990/0227    
		tp = newtlbpid(p); 
		p->pidonmach[m->machno] = tp; 
	} 
	tlbvirt |= PTEPID(tp); 
1991/0425    
	putstlb(tlbvirt, tlbphys); 
1990/0227    
	puttlb(tlbvirt, tlbphys); 
1991/0426/sys/src/9/power/mmu.c:91,1231991/0430/sys/src/9/power/mmu.c:85,133
1990/0227    
	spllo(); 
} 
 
1991/0430    
#ifdef POPCNT 
1990/0227    
void 
1991/0430    
stlbpopcnt(void) 
{ 
	Softtlb *entry, *etab; 
	 
	entry = m->stb; 
	etab = &entry[STLBSIZE]; 
	for(; entry < etab; entry++) 
		if(entry->virt) 
			m->spinlock++; 
 
	m->spinlock /= 2; 
} 
#endif 
 
void 
1990/0227    
purgetlb(int pid) 
{ 
1991/0425    
	Softtlb *entry, *etab; 
1991/0426    
	char *p; 
1991/0425    
	Proc *sp; 
1990/0227    
	int i, rpid; 
1991/0430    
	Proc *sp, **pidproc; 
	int i, rpid, mno; 
1990/0227    
 
1991/0426    
	if(m->pidhere[pid] == 0) 
1990/0227    
		return; 
1991/0425    
                 
	m->tlbpurge++; 
1991/0426    
	p = m->pidhere; 
	memset(m->pidhere, 0, sizeof m->pidhere); 
1991/0425    
	for(i=TLBROFF; i<NTLB; i++) 
		if(TLBPID(gettlbvirt(i)) == pid) 
1990/0227    
			puttlbx(i, KZERO | PTEPID(i), 0); 
1991/0425    
	entry = m->stb; 
	etab = &entry[STLBSIZE]; 
1991/0430    
	mno = m->machno; 
	pidproc = m->pidproc; 
1991/0425    
	for(; entry < etab; entry++){ 
		rpid = TLBPID(entry->virt); 
		if(rpid == pid){ 
1991/0430    
		sp = pidproc[rpid]; 
		if(rpid == pid || !sp || sp->pidonmach[mno] != rpid){ 
1991/0425    
			entry->phys = 0; 
			entry->virt = 0; 
		}else 
			p[rpid] = 1; 
1990/0227    
	} 
1991/0430    
	for(i=TLBROFF; i<NTLB; i++) 
		if(!p[TLBPID(gettlbvirt(i))]) 
			puttlbx(i, KZERO | PTEPID(i), 0); 
1990/0227    
} 
 
void 
1991/0430/sys/src/9/power/mmu.c:40,641991/0501/sys/src/9/power/mmu.c:40,65 (short | long)
1991/0425    
	if(s >= NTLBPID) 
		s = 1; 
	i = s; 
1991/0430    
	for(h = m->pidhere; h[i] && i != s; i = (i == NTLBPID - 1 ? 1 : i + 1)) 
		; 
1991/0425    
	                 
1991/0501    
	h = m->pidhere; 
	do{ 
		i++; 
		if(i >= NTLBPID) 
			i = 1; 
	}while(h[i] && i != s); 
 
1991/0425    
	if(i == s){ 
1991/0426    
		i++; 
		if(i >= NTLBPID) 
			i = 1; 
1991/0425    
	} 
1991/0430    
	                 
1991/0501    
	if(h[i]) 
		purgetlb(i); 
1990/0227    
	sp = m->pidproc[i]; 
1991/0430    
	m->lastpid = i; 
1991/0501    
	if(sp && sp->pidonmach[m->machno] == i) 
		sp->pidonmach[m->machno] = 0; 
1991/0430    
	m->pidproc[i] = p; 
	p->pidonmach[m->machno] = i; 
1990/0227    
	if(sp){ 
1991/0425    
		if(sp->pidonmach[m->machno] == i) 
			sp->pidonmach[m->machno] = 0; 
1991/0430    
		if(h[i]) 
			purgetlb(i); 
1990/0227    
	} 
1991/0501    
	m->lastpid = i; 
1990/0227    
	return i; 
} 
 
1991/0430/sys/src/9/power/mmu.c:85,1321991/0501/sys/src/9/power/mmu.c:86,135
1990/0227    
	spllo(); 
} 
 
1991/0430    
#ifdef POPCNT 
1990/0227    
void 
1991/0430    
stlbpopcnt(void) 
{ 
	Softtlb *entry, *etab; 
	                 
	entry = m->stb; 
	etab = &entry[STLBSIZE]; 
	for(; entry < etab; entry++) 
		if(entry->virt) 
			m->spinlock++; 
                 
	m->spinlock /= 2; 
} 
#endif 
                 
void 
1990/0227    
purgetlb(int pid) 
{ 
1991/0425    
	Softtlb *entry, *etab; 
1991/0426    
	char *p; 
1991/0501    
	char *pidhere; 
1991/0430    
	Proc *sp, **pidproc; 
	int i, rpid, mno; 
1991/0501    
	char dead[NTLBPID]; 
1990/0227    
 
1991/0425    
	m->tlbpurge++; 
1991/0426    
	p = m->pidhere; 
1991/0501    
	/* 
	 * find all pid entries that are no longer used by processes 
	 */ 
	mno = m->machno; 
	pidproc = m->pidproc; 
	memset(dead, 0, sizeof dead); 
	for(i=1; i<NTLBPID; i++){ 
		sp = pidproc[i]; 
		if(!sp || sp->pidonmach[mno] != i){ 
			pidproc[i] = 0; 
			dead[i] = 1; 
		} 
	} 
	dead[pid] = 1; 
	/* 
	 * clean out all dead pids from the stlb; 
	 * garbage collect any pids with no entries 
	 */ 
1991/0426    
	memset(m->pidhere, 0, sizeof m->pidhere); 
1991/0501    
	pidhere = m->pidhere; 
1991/0425    
	entry = m->stb; 
	etab = &entry[STLBSIZE]; 
1991/0430    
	mno = m->machno; 
	pidproc = m->pidproc; 
1991/0425    
	for(; entry < etab; entry++){ 
		rpid = TLBPID(entry->virt); 
1991/0430    
		sp = pidproc[rpid]; 
		if(rpid == pid || !sp || sp->pidonmach[mno] != rpid){ 
1991/0425    
			entry->phys = 0; 
1991/0501    
		if(dead[rpid]) 
1991/0425    
			entry->virt = 0; 
		}else 
			p[rpid] = 1; 
1991/0501    
		else 
			pidhere[rpid] = 1; 
1990/0227    
	} 
1991/0501    
	/* 
	 * clean up the hardware 
	 */ 
1991/0430    
	for(i=TLBROFF; i<NTLB; i++) 
		if(!p[TLBPID(gettlbvirt(i))]) 
1991/0501    
		if(!pidhere[TLBPID(gettlbvirt(i))]) 
1991/0430    
			puttlbx(i, KZERO | PTEPID(i), 0); 
1990/0227    
} 
 
1991/0501/sys/src/9/power/mmu.c:26,311991/0507/sys/src/9/power/mmu.c:26,37 (short | long)
1990/0227    
	u = (User*)USERADDR; 
} 
 
1991/0507    
void 
mmurelease(Proc *p) 
{ 
	memset(p->pidonmach, 0, sizeof p->pidonmach); 
} 
 
1990/0227    
/* 
 * Process must be non-interruptible 
 */ 
1991/0507/sys/src/9/power/mmu.c:13,181991/0705/sys/src/9/power/mmu.c:13,24 (short | long)
1990/0227    
	short tp; 
	ulong tlbvirt, tlbphys; 
 
1991/0705    
	if(p->newtlb) { 
		/* see flushmmu. */ 
		memset(p->pidonmach, 0, sizeof p->pidonmach); 
		p->newtlb = 0; 
	} 
 
1990/0227    
	tp = p->pidonmach[m->machno]; 
1991/0430    
	if(tp == 0) 
1990/0227    
		tp = newtlbpid(p); 
1991/0507/sys/src/9/power/mmu.c:70,811991/0705/sys/src/9/power/mmu.c:76,96
1990/0227    
} 
 
void 
putmmu(ulong tlbvirt, ulong tlbphys) 
1991/0705    
putmmu(ulong tlbvirt, ulong tlbphys, Page *pg) 
1990/0227    
{ 
	short tp; 
	Proc *p; 
1991/0705    
	char *ctl; 
1990/0227    
 
	splhi(); 
1991/0705    
 
	ctl = &pg->cachectl[m->machno];  
	if(*ctl == PG_TXTFLUSH) { 
		dcflush((void*)pg->pa, BY2PG); 
		icflush((void*)pg->pa, BY2PG); 
		*ctl = PG_NOFLUSH; 
	} 
 
1990/0227    
	p = u->p; 
/*	if(p->state != Running) 
		panic("putmmu state %lux %lux %s\n", u, p, statename[p->state]); 
1991/0705/sys/src/9/power/mmu.c:95,1011991/0926/sys/src/9/power/mmu.c:95,100 (short | long)
1990/0227    
/*	if(p->state != Running) 
		panic("putmmu state %lux %lux %s\n", u, p, statename[p->state]); 
*/ 
	p->state = MMUing; 
	tp = p->pidonmach[m->machno]; 
1991/0430    
	if(tp == 0) 
1990/0227    
		tp = newtlbpid(p); 
1991/0705/sys/src/9/power/mmu.c:103,1091991/0926/sys/src/9/power/mmu.c:102,107
1991/0425    
	putstlb(tlbvirt, tlbphys); 
1990/0227    
	puttlb(tlbvirt, tlbphys); 
	m->pidhere[tp] = 1; 
	p->state = Running; 
	spllo(); 
} 
 
1991/0926/sys/src/9/power/mmu.c:22,281991/0928/sys/src/9/power/mmu.c:22,28 (short | long)
1990/0227    
	tp = p->pidonmach[m->machno]; 
1991/0430    
	if(tp == 0) 
1990/0227    
		tp = newtlbpid(p); 
/*	if(p->upage->va != (USERADDR|(p->pid&0xFFFF))) 
1991/0928    
/*	if(p->upage->va != (USERADDR|(p->pid&0xFFFF)) && p->pid != 0) 
1990/0227    
		panic("mapstack %d 0x%lux 0x%lux", p->pid, p->upage->pa, p->upage->va); 
*/ 
1991/0430    
	/* don't set m->pidhere[tp] because we're only writing entry 0 */ 
1991/0928/sys/src/9/power/mmu.c:156,1641992/0106/sys/src/9/power/mmu.c:156,162 (short | long)
1990/0227    
flushmmu(void) 
{ 
	splhi(); 
	/* easiest is to forget what pid we had.... */ 
	memset(u->p->pidonmach, 0, sizeof u->p->pidonmach); 
	/* ....then get a new one by trying to map our stack */ 
1992/0106    
	u->p->newtlb = 1; 
1990/0227    
	mapstack(u->p); 
	spllo(); 
} 
1992/0106/sys/src/9/power/mmu.c:1,51992/0321/sys/src/9/power/mmu.c:1,5 (short | long)
1990/0227    
#include	"u.h" 
#include	"lib.h" 
1992/0321    
#include	"../port/lib.h" 
1990/0227    
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
1992/0321/sys/src/9/power/mmu.c:14,201992/1130/sys/src/9/power/mmu.c:14,19 (short | long)
1990/0227    
	ulong tlbvirt, tlbphys; 
 
1991/0705    
	if(p->newtlb) { 
		/* see flushmmu. */ 
		memset(p->pidonmach, 0, sizeof p->pidonmach); 
		p->newtlb = 0; 
	} 
1992/0321/sys/src/9/power/mmu.c:22,331992/1130/sys/src/9/power/mmu.c:21,29
1990/0227    
	tp = p->pidonmach[m->machno]; 
1991/0430    
	if(tp == 0) 
1990/0227    
		tp = newtlbpid(p); 
1991/0928    
/*	if(p->upage->va != (USERADDR|(p->pid&0xFFFF)) && p->pid != 0) 
1990/0227    
		panic("mapstack %d 0x%lux 0x%lux", p->pid, p->upage->pa, p->upage->va); 
*/ 
1991/0430    
	/* don't set m->pidhere[tp] because we're only writing entry 0 */ 
1992/1130    
 
1990/0227    
	tlbvirt = USERADDR | PTEPID(tp); 
	tlbphys = p->upage->pa | PTEWRITE | PTEVALID | PTEGLOBL; 
1992/1130    
	tlbphys = p->upage->pa | PTEWRITE|PTEVALID|PTEGLOBL; 
1990/0227    
	puttlbx(0, tlbvirt, tlbphys); 
	u = (User*)USERADDR; 
} 
1992/0321/sys/src/9/power/mmu.c:66,711992/1130/sys/src/9/power/mmu.c:62,68
1991/0425    
	} 
1991/0501    
	if(h[i]) 
		purgetlb(i); 
1992/1130    
 
1990/0227    
	sp = m->pidproc[i]; 
1991/0501    
	if(sp && sp->pidonmach[m->machno] == i) 
		sp->pidonmach[m->machno] = 0; 
1992/0321/sys/src/9/power/mmu.c:92,1031992/1130/sys/src/9/power/mmu.c:89,98
1991/0705    
	} 
 
1990/0227    
	p = u->p; 
/*	if(p->state != Running) 
		panic("putmmu state %lux %lux %s\n", u, p, statename[p->state]); 
*/ 
	tp = p->pidonmach[m->machno]; 
1991/0430    
	if(tp == 0) 
1990/0227    
		tp = newtlbpid(p); 
1992/1130    
 
1990/0227    
	tlbvirt |= PTEPID(tp); 
1991/0425    
	putstlb(tlbvirt, tlbphys); 
1990/0227    
	puttlb(tlbvirt, tlbphys); 
1992/0321/sys/src/9/power/mmu.c:131,1371992/1130/sys/src/9/power/mmu.c:126,132
1991/0501    
	dead[pid] = 1; 
	/* 
	 * clean out all dead pids from the stlb; 
	 * garbage collect any pids with no entries 
1992/1130    
	 * garbage collect pids with no entries 
1991/0501    
	 */ 
1991/0426    
	memset(m->pidhere, 0, sizeof m->pidhere); 
1991/0501    
	pidhere = m->pidhere; 
1992/0321/sys/src/9/power/mmu.c:178,1831992/1130/sys/src/9/power/mmu.c:173,179
1991/0425    
{ 
	Softtlb *entry; 
 
1992/1130    
	/* This hash function is also coded into utlbmiss in l.s */ 
1991/0425    
	entry = &m->stb[((tlbvirt<<1) ^ (tlbvirt>>12)) & (STLBSIZE-1)]; 
	entry->phys = tlbphys; 
	entry->virt = tlbvirt; 
1992/1130/sys/src/9/power/mmu.c:180,1821993/0209/sys/src/9/power/mmu.c:180,222 (short | long)
1991/0425    
	if(tlbphys == 0) 
		entry->virt = 0; 
1990/1211    
} 
1993/0209    
 
/* Mapping routines for td's frame buffer 
Page* 
a16seg(Segment *s, ulong va) 
{ 
	Page *pg; 
 
	pg = smalloc(sizeof(Page)); 
	memset(pg, 0, sizeof(Page)); 
	pg->va = va; 
	pg->pa = 0xd0000 + (va - s->base); 
	pg->ref = 1; 
	return pg; 
} 
 
Page* 
a32seg(Segment *s, ulong va) 
{ 
	Page *pg; 
 
	pg = smalloc(sizeof(Page)); 
	memset(pg, 0, sizeof(Page)); 
	pg->va = va; 
	pg->pa = VMEA32SUP(ulong, va - s->base); 
	pg->ref = 1; 
	return pg; 
} 
 
void 
vmefree(Page *pg) 
{ 
	int x; 
 
	lock(pg); 
	x = --pg->ref; 
	unlock(pg); 
	if(x <= 0) 
		free(pg); 
} 
*/ 
1993/0209/sys/src/9/power/mmu.c:180,2221993/0210/sys/src/9/power/mmu.c:180,182 (short | long)
1991/0425    
	if(tlbphys == 0) 
		entry->virt = 0; 
1990/1211    
} 
1993/0209    
                 
/* Mapping routines for td's frame buffer 
Page* 
a16seg(Segment *s, ulong va) 
{ 
	Page *pg; 
                 
	pg = smalloc(sizeof(Page)); 
	memset(pg, 0, sizeof(Page)); 
	pg->va = va; 
	pg->pa = 0xd0000 + (va - s->base); 
	pg->ref = 1; 
	return pg; 
} 
                 
Page* 
a32seg(Segment *s, ulong va) 
{ 
	Page *pg; 
                 
	pg = smalloc(sizeof(Page)); 
	memset(pg, 0, sizeof(Page)); 
	pg->va = va; 
	pg->pa = VMEA32SUP(ulong, va - s->base); 
	pg->ref = 1; 
	return pg; 
} 
                 
void 
vmefree(Page *pg) 
{ 
	int x; 
                 
	lock(pg); 
	x = --pg->ref; 
	unlock(pg); 
	if(x <= 0) 
		free(pg); 
} 
*/ 
1993/0210/sys/src/9/power/mmu.c:4,311993/0501/sys/src/9/power/mmu.c:4,20 (short | long)
1990/0227    
#include	"dat.h" 
#include	"fns.h" 
 
/* 
 * Called splhi, not in Running state 
 */ 
void 
mapstack(Proc *p) 
1993/0501    
mmuswitch(Proc *p) 
1990/0227    
{ 
	short tp; 
	ulong tlbvirt, tlbphys; 
                 
1991/0705    
	if(p->newtlb) { 
		memset(p->pidonmach, 0, sizeof p->pidonmach); 
		p->newtlb = 0; 
	} 
1993/0501    
	if(p->pidonmach[m->machno] == 0) 
		newtlbpid(p); 
1991/0705    
 
1990/0227    
	tp = p->pidonmach[m->machno]; 
1991/0430    
	if(tp == 0) 
1990/0227    
		tp = newtlbpid(p); 
1992/1130    
                 
1990/0227    
	tlbvirt = USERADDR | PTEPID(tp); 
1992/1130    
	tlbphys = p->upage->pa | PTEWRITE|PTEVALID|PTEGLOBL; 
1990/0227    
	puttlbx(0, tlbvirt, tlbphys); 
	u = (User*)USERADDR; 
1993/0501    
	putcontext(p->pidonmach[m->machno]); 
1990/0227    
} 
 
1991/0507    
void 
1993/0210/sys/src/9/power/mmu.c:76,821993/0501/sys/src/9/power/mmu.c:65,70
1991/0705    
putmmu(ulong tlbvirt, ulong tlbphys, Page *pg) 
1990/0227    
{ 
	short tp; 
	Proc *p; 
1991/0705    
	char *ctl; 
1990/0227    
 
	splhi(); 
1993/0210/sys/src/9/power/mmu.c:88,971993/0501/sys/src/9/power/mmu.c:76,84
1991/0705    
		*ctl = PG_NOFLUSH; 
	} 
 
1990/0227    
	p = u->p; 
	tp = p->pidonmach[m->machno]; 
1993/0501    
	tp = up->pidonmach[m->machno]; 
1991/0430    
	if(tp == 0) 
1990/0227    
		tp = newtlbpid(p); 
1993/0501    
		tp = newtlbpid(up); 
1992/1130    
 
1990/0227    
	tlbvirt |= PTEPID(tp); 
1991/0425    
	putstlb(tlbvirt, tlbphys); 
1993/0210/sys/src/9/power/mmu.c:151,1581993/0501/sys/src/9/power/mmu.c:138,145
1990/0227    
flushmmu(void) 
{ 
	splhi(); 
1992/0106    
	u->p->newtlb = 1; 
1990/0227    
	mapstack(u->p); 
1993/0501    
	up->newtlb = 1; 
	mmuswitch(up); 
1990/0227    
	spllo(); 
} 
1990/1211    
 
1993/0210/sys/src/9/power/mmu.c:159,1711993/0501/sys/src/9/power/mmu.c:146,151
1990/1211    
void 
clearmmucache(void) 
{ 
} 
                 
void 
invalidateu(void) 
{ 
	puttlbx(0, KZERO | PTEPID(0), 0); 
1991/0425    
	putstlb(KZERO | PTEPID(0), 0); 
} 
 
void 
1993/0501/sys/src/9/power/mmu.c:70,791993/0806/sys/src/9/power/mmu.c:70,79 (short | long)
1990/0227    
	splhi(); 
1991/0705    
 
	ctl = &pg->cachectl[m->machno];  
	if(*ctl == PG_TXTFLUSH) { 
1993/0806    
	if(*ctl & PG_TXTFLUSH) { 
1991/0705    
		dcflush((void*)pg->pa, BY2PG); 
		icflush((void*)pg->pa, BY2PG); 
		*ctl = PG_NOFLUSH; 
1993/0806    
		*ctl &= ~PG_TXTFLUSH; 
1991/0705    
	} 
 
1993/0501    
	tp = up->pidonmach[m->machno]; 
1993/0806/sys/src/9/power/mmu.c:70,761993/0812/sys/src/9/power/mmu.c:70,76 (short | long)
1990/0227    
	splhi(); 
1991/0705    
 
	ctl = &pg->cachectl[m->machno];  
1993/0806    
	if(*ctl & PG_TXTFLUSH) { 
1993/0812    
	if(*ctl == PG_TXTFLUSH) { 
1991/0705    
		dcflush((void*)pg->pa, BY2PG); 
		icflush((void*)pg->pa, BY2PG); 
1993/0806    
		*ctl &= ~PG_TXTFLUSH; 
1993/0812/sys/src/9/power/mmu.c:7,201994/0406/sys/src/9/power/mmu.c:7,23 (short | long)
1990/0227    
void 
1993/0501    
mmuswitch(Proc *p) 
1990/0227    
{ 
1994/0406    
	int tp; 
 
1991/0705    
	if(p->newtlb) { 
		memset(p->pidonmach, 0, sizeof p->pidonmach); 
		p->newtlb = 0; 
	} 
1993/0501    
	if(p->pidonmach[m->machno] == 0) 
		newtlbpid(p); 
1994/0406    
	tp = p->pidonmach[m->machno]; 
	if(tp == 0) 
		tp = newtlbpid(p); 
1991/0705    
 
1993/0501    
	putcontext(p->pidonmach[m->machno]); 
1994/0406    
	putcontext(tp); 
1990/0227    
} 
 
1991/0507    
void 
1993/0812/sys/src/9/power/mmu.c:30,631994/0406/sys/src/9/power/mmu.c:33,59
1990/0227    
newtlbpid(Proc *p) 
{ 
1991/0425    
	int i, s; 
1990/0227    
	Proc *sp; 
1991/0425    
	char *h; 
1994/0406    
	Proc **h; 
1991/0426    
 
1991/0425    
	s = m->lastpid; 
	if(s >= NTLBPID) 
		s = 1; 
	i = s; 
1991/0501    
	h = m->pidhere; 
	do{ 
1994/0406    
	i = m->lastpid; 
	h = m->pidproc; 
	for(s = 0; s < NTLBPID; s++) { 
1991/0501    
		i++; 
		if(i >= NTLBPID) 
			i = 1; 
	}while(h[i] && i != s); 
                 
1991/0425    
	if(i == s){ 
1991/0426    
		i++; 
		if(i >= NTLBPID) 
			i = 1; 
1994/0406    
		if(h[i] == 0) 
			break; 
1991/0425    
	} 
1994/0406    
 
1991/0501    
	if(h[i]) 
		purgetlb(i); 
1994/0406    
	if(h[i] != 0) 
		panic("newtlb"); 
1992/1130    
 
1990/0227    
	sp = m->pidproc[i]; 
1991/0501    
	if(sp && sp->pidonmach[m->machno] == i) 
		sp->pidonmach[m->machno] = 0; 
1991/0430    
	m->pidproc[i] = p; 
	p->pidonmach[m->machno] = i; 
1991/0501    
	m->lastpid = i; 
1994/0406    
 
1990/0227    
	return i; 
} 
 
1993/0812/sys/src/9/power/mmu.c:73,791994/0406/sys/src/9/power/mmu.c:69,75
1993/0812    
	if(*ctl == PG_TXTFLUSH) { 
1991/0705    
		dcflush((void*)pg->pa, BY2PG); 
		icflush((void*)pg->pa, BY2PG); 
1993/0806    
		*ctl &= ~PG_TXTFLUSH; 
1994/0406    
		*ctl = PG_NOFLUSH; 
1991/0705    
	} 
 
1993/0501    
	tp = up->pidonmach[m->machno]; 
1993/0812/sys/src/9/power/mmu.c:83,1361994/0406/sys/src/9/power/mmu.c:79,128
1990/0227    
	tlbvirt |= PTEPID(tp); 
1991/0425    
	putstlb(tlbvirt, tlbphys); 
1990/0227    
	puttlb(tlbvirt, tlbphys); 
	m->pidhere[tp] = 1; 
	spllo(); 
} 
 
void 
purgetlb(int pid) 
1994/0406    
purgetlb(int tlbpid) 
1990/0227    
{ 
1991/0425    
	Softtlb *entry, *etab; 
1991/0501    
	char *pidhere; 
1994/0406    
	int i, mno; 
1991/0430    
	Proc *sp, **pidproc; 
	int i, rpid, mno; 
1991/0501    
	char dead[NTLBPID]; 
1994/0406    
	Softtlb *entry, *etab; 
1990/0227    
 
1991/0425    
	m->tlbpurge++; 
1994/0406    
 
1991/0501    
	/* 
	 * find all pid entries that are no longer used by processes 
	 */ 
	mno = m->machno; 
	pidproc = m->pidproc; 
	memset(dead, 0, sizeof dead); 
	for(i=1; i<NTLBPID; i++){ 
1994/0406    
	for(i=1; i<NTLBPID; i++) { 
1991/0501    
		sp = pidproc[i]; 
		if(!sp || sp->pidonmach[mno] != i){ 
1994/0406    
		if(sp && sp->pidonmach[mno] != i) 
1991/0501    
			pidproc[i] = 0; 
			dead[i] = 1; 
		} 
	} 
	dead[pid] = 1; 
1994/0406    
 
1991/0501    
	/* 
	 * clean out all dead pids from the stlb; 
1992/1130    
	 * garbage collect pids with no entries 
1994/0406    
	 * shoot down the one we want 
1991/0501    
	 */ 
1991/0426    
	memset(m->pidhere, 0, sizeof m->pidhere); 
1991/0501    
	pidhere = m->pidhere; 
1994/0406    
	sp = pidproc[tlbpid]; 
	if(sp != 0) 
		sp->pidonmach[mno] = 0; 
	pidproc[tlbpid] = 0; 
 
	/* 
	 * clean out all dead tlbpids from the stlb; 
	 */ 
1991/0425    
	entry = m->stb; 
	etab = &entry[STLBSIZE]; 
	for(; entry < etab; entry++){ 
		rpid = TLBPID(entry->virt); 
1991/0501    
		if(dead[rpid]) 
1994/0406    
	for(etab = &entry[STLBSIZE]; entry < etab; entry++) 
		if(pidproc[TLBPID(entry->virt)] == 0) 
1991/0425    
			entry->virt = 0; 
1991/0501    
		else 
			pidhere[rpid] = 1; 
1990/0227    
	} 
1994/0406    
 
1991/0501    
	/* 
	 * clean up the hardware 
	 */ 
1991/0430    
	for(i=TLBROFF; i<NTLB; i++) 
1991/0501    
		if(!pidhere[TLBPID(gettlbvirt(i))]) 
1994/0406    
		if(pidproc[TLBPID(gettlbvirt(i))] == 0) 
1991/0430    
			puttlbx(i, KZERO | PTEPID(i), 0); 
1990/0227    
} 
 
1994/0406/sys/src/9/power/mmu.c:1,1541997/0327/sys/src/9/power/mmu.c:0 (short | long)
Deleted.
rsc Mon Mar 7 10:33:00 2005
1990/0227    
#include	"u.h" 
1992/0321    
#include	"../port/lib.h" 
1990/0227    
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
                 
void 
1993/0501    
mmuswitch(Proc *p) 
1990/0227    
{ 
1994/0406    
	int tp; 
                 
1991/0705    
	if(p->newtlb) { 
		memset(p->pidonmach, 0, sizeof p->pidonmach); 
		p->newtlb = 0; 
	} 
1994/0406    
	tp = p->pidonmach[m->machno]; 
	if(tp == 0) 
		tp = newtlbpid(p); 
1991/0705    
                 
1994/0406    
	putcontext(tp); 
1990/0227    
} 
                 
1991/0507    
void 
mmurelease(Proc *p) 
{ 
	memset(p->pidonmach, 0, sizeof p->pidonmach); 
} 
                 
1990/0227    
/* 
 * Process must be non-interruptible 
 */ 
int 
newtlbpid(Proc *p) 
{ 
1991/0425    
	int i, s; 
1994/0406    
	Proc **h; 
1991/0426    
                 
1994/0406    
	i = m->lastpid; 
	h = m->pidproc; 
	for(s = 0; s < NTLBPID; s++) { 
1991/0501    
		i++; 
		if(i >= NTLBPID) 
			i = 1; 
1994/0406    
		if(h[i] == 0) 
			break; 
1991/0425    
	} 
1994/0406    
                 
1991/0501    
	if(h[i]) 
		purgetlb(i); 
1994/0406    
	if(h[i] != 0) 
		panic("newtlb"); 
1992/1130    
                 
1991/0430    
	m->pidproc[i] = p; 
	p->pidonmach[m->machno] = i; 
1991/0501    
	m->lastpid = i; 
1994/0406    
                 
1990/0227    
	return i; 
} 
                 
void 
1991/0705    
putmmu(ulong tlbvirt, ulong tlbphys, Page *pg) 
1990/0227    
{ 
	short tp; 
1991/0705    
	char *ctl; 
1990/0227    
                 
	splhi(); 
1991/0705    
                 
	ctl = &pg->cachectl[m->machno];  
1993/0812    
	if(*ctl == PG_TXTFLUSH) { 
1991/0705    
		dcflush((void*)pg->pa, BY2PG); 
		icflush((void*)pg->pa, BY2PG); 
1994/0406    
		*ctl = PG_NOFLUSH; 
1991/0705    
	} 
                 
1993/0501    
	tp = up->pidonmach[m->machno]; 
1991/0430    
	if(tp == 0) 
1993/0501    
		tp = newtlbpid(up); 
1992/1130    
                 
1990/0227    
	tlbvirt |= PTEPID(tp); 
1991/0425    
	putstlb(tlbvirt, tlbphys); 
1990/0227    
	puttlb(tlbvirt, tlbphys); 
	spllo(); 
} 
                 
void 
1994/0406    
purgetlb(int tlbpid) 
1990/0227    
{ 
1994/0406    
	int i, mno; 
1991/0430    
	Proc *sp, **pidproc; 
1994/0406    
	Softtlb *entry, *etab; 
1990/0227    
                 
1991/0425    
	m->tlbpurge++; 
1994/0406    
                 
1991/0501    
	/* 
	 * find all pid entries that are no longer used by processes 
	 */ 
	mno = m->machno; 
	pidproc = m->pidproc; 
1994/0406    
	for(i=1; i<NTLBPID; i++) { 
1991/0501    
		sp = pidproc[i]; 
1994/0406    
		if(sp && sp->pidonmach[mno] != i) 
1991/0501    
			pidproc[i] = 0; 
	} 
1994/0406    
                 
1991/0501    
	/* 
1994/0406    
	 * shoot down the one we want 
1991/0501    
	 */ 
1994/0406    
	sp = pidproc[tlbpid]; 
	if(sp != 0) 
		sp->pidonmach[mno] = 0; 
	pidproc[tlbpid] = 0; 
                 
	/* 
	 * clean out all dead tlbpids from the stlb; 
	 */ 
1991/0425    
	entry = m->stb; 
1994/0406    
	for(etab = &entry[STLBSIZE]; entry < etab; entry++) 
		if(pidproc[TLBPID(entry->virt)] == 0) 
1991/0425    
			entry->virt = 0; 
1994/0406    
                 
1991/0501    
	/* 
	 * clean up the hardware 
	 */ 
1991/0430    
	for(i=TLBROFF; i<NTLB; i++) 
1994/0406    
		if(pidproc[TLBPID(gettlbvirt(i))] == 0) 
1991/0430    
			puttlbx(i, KZERO | PTEPID(i), 0); 
1990/0227    
} 
                 
void 
flushmmu(void) 
{ 
	splhi(); 
1993/0501    
	up->newtlb = 1; 
	mmuswitch(up); 
1990/0227    
	spllo(); 
} 
1990/1211    
                 
void 
clearmmucache(void) 
{ 
1991/0425    
} 
                 
void 
putstlb(ulong tlbvirt, ulong tlbphys) 
{ 
	Softtlb *entry; 
                 
1992/1130    
	/* This hash function is also coded into utlbmiss in l.s */ 
1991/0425    
	entry = &m->stb[((tlbvirt<<1) ^ (tlbvirt>>12)) & (STLBSIZE-1)]; 
	entry->phys = tlbphys; 
	entry->virt = tlbvirt; 
	if(tlbphys == 0) 
		entry->virt = 0; 
1990/1211    
} 


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