~kris/9p

9hist

ref: f3ed7ed7170f0286215ba6ffe62c8d3494de6cbd 9hist/power/mmu.c -rw-r--r-- 1.8 KiB
f3ed7ed7 — David du Colombier Plan 9 from Bell Labs 1990-04-24 36 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"

/*
 * Called splhi, not in Running state
 */
void
mapstack(Proc *p)
{
	short tp;
	ulong tlbvirt, tlbphys;

	tp = p->pidonmach[m->machno];
	if(tp == 0){
		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 */
	tlbvirt = USERADDR | PTEPID(tp);
	tlbphys = p->upage->pa | PTEWRITE | PTEVALID | PTEGLOBL;
	puttlbx(0, tlbvirt, tlbphys);
	u = (User*)USERADDR;
}

/*
 * Process must be non-interruptible
 */
int
newtlbpid(Proc *p)
{
	int i;
	Proc *sp;

	i = m->lastpid+1;
	if(i >= NTLBPID)
		i = 1;
	sp = m->pidproc[i];
	if(sp){
		sp->pidonmach[m->machno] = 0;
		purgetlb(i);
	}
	m->pidproc[i] = p;
	m->lastpid = i;
	return i;
}

void
putmmu(ulong tlbvirt, ulong tlbphys)
{
	short tp;
	Proc *p;

	splhi();
	p = u->p;
/*	if(p->state != Running)
		panic("putmmu state %lux %lux %s\n", u, p, statename[p->state]);
*/
	p->state = MMUing;
	tp = p->pidonmach[m->machno];
	if(tp == 0){
		tp = newtlbpid(p);
		p->pidonmach[m->machno] = tp;
	}
	tlbvirt |= PTEPID(tp);
	puttlb(tlbvirt, tlbphys);
	m->pidhere[tp] = 1;
	p->state = Running;
	spllo();
}

void
purgetlb(int pid)
{
	int i, rpid;

	if(m->pidhere[pid] == 0)
		return;
	memset(m->pidhere, 0, sizeof m->pidhere);
	for(i=TLBROFF; i<NTLB; i++){
		rpid = (gettlbvirt(i)>>6) & 0x3F;
		if(rpid == pid)
			puttlbx(i, KZERO | PTEPID(i), 0);
		else
			m->pidhere[rpid] = 1;
	}
}

void
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 */
	mapstack(u->p);
	spllo();
}