xref: /plan9-contrib/sys/src/9/vt4/mmu.c (revision d6dfd9ef91cf0fa8514a249d5f2a550978c19369)
1*d6dfd9efSDavid du Colombier #include	"u.h"
2*d6dfd9efSDavid du Colombier #include	"../port/lib.h"
3*d6dfd9efSDavid du Colombier #include	"mem.h"
4*d6dfd9efSDavid du Colombier #include	"dat.h"
5*d6dfd9efSDavid du Colombier #include	"fns.h"
6*d6dfd9efSDavid du Colombier 
7*d6dfd9efSDavid du Colombier /*
8*d6dfd9efSDavid du Colombier  * l.s has set some global TLB entries for the kernel at
9*d6dfd9efSDavid du Colombier  * the top of the tlb (NTLB-1 down), partly to account for
10*d6dfd9efSDavid du Colombier  * the way the firmware sets things up on some platforms (eg, 440).
11*d6dfd9efSDavid du Colombier  * The first entry not used by the kernel (eg, by kmapphys) is m->utlbhi.
12*d6dfd9efSDavid du Colombier  * User tlbs are assigned indices from 0 to m->utlbhi, round-robin.
13*d6dfd9efSDavid du Colombier  * m->utlbnext is the next to use.  Kernel tlbs are added at utlbhi, which then moves.
14*d6dfd9efSDavid du Colombier  *
15*d6dfd9efSDavid du Colombier  * In this version, the kernel TLB entries are in zone 0,
16*d6dfd9efSDavid du Colombier  * and user pages are in zone 1.  The kernel entries are also PID 0 (global)
17*d6dfd9efSDavid du Colombier  * so they are usable as the PID changes (0=no user; non-zero=user process mapped).
18*d6dfd9efSDavid du Colombier   */
19*d6dfd9efSDavid du Colombier 
20*d6dfd9efSDavid du Colombier enum {
21*d6dfd9efSDavid du Colombier 	DEBUG = 0,
22*d6dfd9efSDavid du Colombier 	Minutlb=	NTLB/2,	/* at least this many for user process */
23*d6dfd9efSDavid du Colombier };
24*d6dfd9efSDavid du Colombier 
25*d6dfd9efSDavid du Colombier Softtlb	softtlb[MAXMACH][STLBSIZE];
26*d6dfd9efSDavid du Colombier 
27*d6dfd9efSDavid du Colombier static int	newtlbpid(Proc*);
28*d6dfd9efSDavid du Colombier static void	purgetlb(int);
29*d6dfd9efSDavid du Colombier static void putstlb(int, u32int, u32int);
30*d6dfd9efSDavid du Colombier 
31*d6dfd9efSDavid du Colombier /* clobbers SPR_PID */
32*d6dfd9efSDavid du Colombier static int
probehi(uintptr va)33*d6dfd9efSDavid du Colombier probehi(uintptr va)
34*d6dfd9efSDavid du Colombier {
35*d6dfd9efSDavid du Colombier 	int i;
36*d6dfd9efSDavid du Colombier 
37*d6dfd9efSDavid du Colombier 	for (i = 0; i < NTLBPID; i++) {
38*d6dfd9efSDavid du Colombier 		putpid(i);
39*d6dfd9efSDavid du Colombier 		if (tlbsxcc(va) >= 0)
40*d6dfd9efSDavid du Colombier 			return i;
41*d6dfd9efSDavid du Colombier 	}
42*d6dfd9efSDavid du Colombier 	return -1;
43*d6dfd9efSDavid du Colombier }
44*d6dfd9efSDavid du Colombier 
45*d6dfd9efSDavid du Colombier void
tlbdump(char * s)46*d6dfd9efSDavid du Colombier tlbdump(char *s)
47*d6dfd9efSDavid du Colombier {
48*d6dfd9efSDavid du Colombier 	int i, p, ppid;
49*d6dfd9efSDavid du Colombier 	u32int hi, lo;
50*d6dfd9efSDavid du Colombier 
51*d6dfd9efSDavid du Colombier 	p = getpid();
52*d6dfd9efSDavid du Colombier 	iprint("tlb[%s] pid %d lastpid %d\n", s, p, m->lastpid);
53*d6dfd9efSDavid du Colombier 	for(i=0; i<NTLB; i++){
54*d6dfd9efSDavid du Colombier 		hi = tlbrehi(i);
55*d6dfd9efSDavid du Colombier 		if(hi & TLBVALID){
56*d6dfd9efSDavid du Colombier 			ppid = probehi(TLBEPN(hi));
57*d6dfd9efSDavid du Colombier 			lo = tlbrelo(i);
58*d6dfd9efSDavid du Colombier 			iprint("%.2d hi %#8.8ux pid %d lo %#8.8ux\n",
59*d6dfd9efSDavid du Colombier 				i, hi, ppid, lo);
60*d6dfd9efSDavid du Colombier 		}
61*d6dfd9efSDavid du Colombier 		if(i == m->utlbhi)
62*d6dfd9efSDavid du Colombier 			iprint("-----\n");
63*d6dfd9efSDavid du Colombier 	}
64*d6dfd9efSDavid du Colombier 	putpid(p);	/* tlbrehi changes PID */
65*d6dfd9efSDavid du Colombier }
66*d6dfd9efSDavid du Colombier 
67*d6dfd9efSDavid du Colombier /*
68*d6dfd9efSDavid du Colombier  * l.s provides a set of tlb entries for the kernel, allocating
69*d6dfd9efSDavid du Colombier  * them starting at the highest index down.  user-level entries
70*d6dfd9efSDavid du Colombier  * will be allocated from index 0 up.
71*d6dfd9efSDavid du Colombier  */
72*d6dfd9efSDavid du Colombier void
mmuinit(void)73*d6dfd9efSDavid du Colombier mmuinit(void)
74*d6dfd9efSDavid du Colombier {
75*d6dfd9efSDavid du Colombier 	int i;
76*d6dfd9efSDavid du Colombier 
77*d6dfd9efSDavid du Colombier 	if(DEBUG)
78*d6dfd9efSDavid du Colombier 		tlbdump("init0");
79*d6dfd9efSDavid du Colombier 	m->lastpid = 0;
80*d6dfd9efSDavid du Colombier 	m->utlbhi = 0;
81*d6dfd9efSDavid du Colombier 	for(i = 0; i < NTLB; i++){
82*d6dfd9efSDavid du Colombier 		if(tlbrehi(i) & TLBVALID)
83*d6dfd9efSDavid du Colombier 			break;
84*d6dfd9efSDavid du Colombier 		m->utlbhi = i;
85*d6dfd9efSDavid du Colombier 		tlbwrx(i, 0, 0);
86*d6dfd9efSDavid du Colombier 	}
87*d6dfd9efSDavid du Colombier 	if(DEBUG)
88*d6dfd9efSDavid du Colombier 		tlbdump("init1");
89*d6dfd9efSDavid du Colombier 	putpid(0);
90*d6dfd9efSDavid du Colombier 
91*d6dfd9efSDavid du Colombier 	m->stlb = softtlb[m->machno];
92*d6dfd9efSDavid du Colombier 	m->pstlb = PADDR(m->stlb);
93*d6dfd9efSDavid du Colombier 
94*d6dfd9efSDavid du Colombier 	/*
95*d6dfd9efSDavid du Colombier 	 * set OCM mapping, assuming:
96*d6dfd9efSDavid du Colombier 	 *	caches were invalidated earlier;
97*d6dfd9efSDavid du Colombier 	 *	and we aren't currently using it
98*d6dfd9efSDavid du Colombier 	 * must also set a tlb entry that validates the virtual address but
99*d6dfd9efSDavid du Colombier 	 * the translation is not used (see p. 5-2)
100*d6dfd9efSDavid du Colombier 	 */
101*d6dfd9efSDavid du Colombier /*
102*d6dfd9efSDavid du Colombier 	putdcr(Isarc, OCMZERO);
103*d6dfd9efSDavid du Colombier 	putdcr(Dsarc, OCMZERO);
104*d6dfd9efSDavid du Colombier 	putdcr(Iscntl, Isen);
105*d6dfd9efSDavid du Colombier 	putdcr(Iscntl, Dsen|Dof);
106*d6dfd9efSDavid du Colombier 	tlbwrx(tlbx, OCMZERO|TLB4K|TLBVALID, OCMZERO|TLBZONE(0)|TLBWR|TLBEX|TLBI);
107*d6dfd9efSDavid du Colombier 	tlbx--;
108*d6dfd9efSDavid du Colombier */
109*d6dfd9efSDavid du Colombier }
110*d6dfd9efSDavid du Colombier 
111*d6dfd9efSDavid du Colombier void
flushmmu(void)112*d6dfd9efSDavid du Colombier flushmmu(void)
113*d6dfd9efSDavid du Colombier {
114*d6dfd9efSDavid du Colombier 	int x;
115*d6dfd9efSDavid du Colombier 
116*d6dfd9efSDavid du Colombier 	x = splhi();
117*d6dfd9efSDavid du Colombier 	up->newtlb = 1;
118*d6dfd9efSDavid du Colombier 	mmuswitch(up);
119*d6dfd9efSDavid du Colombier 	splx(x);
120*d6dfd9efSDavid du Colombier }
121*d6dfd9efSDavid du Colombier 
122*d6dfd9efSDavid du Colombier /*
123*d6dfd9efSDavid du Colombier  * called with splhi
124*d6dfd9efSDavid du Colombier  */
125*d6dfd9efSDavid du Colombier void
mmuswitch(Proc * p)126*d6dfd9efSDavid du Colombier mmuswitch(Proc *p)
127*d6dfd9efSDavid du Colombier {
128*d6dfd9efSDavid du Colombier 	int tp;
129*d6dfd9efSDavid du Colombier 
130*d6dfd9efSDavid du Colombier 	if(p->newtlb){
131*d6dfd9efSDavid du Colombier 		p->mmupid = 0;
132*d6dfd9efSDavid du Colombier 		p->newtlb = 0;
133*d6dfd9efSDavid du Colombier 	}
134*d6dfd9efSDavid du Colombier 	tp = p->mmupid;
135*d6dfd9efSDavid du Colombier 	if(tp == 0 && !p->kp)
136*d6dfd9efSDavid du Colombier 		tp = newtlbpid(p);
137*d6dfd9efSDavid du Colombier 	putpid(tp);
138*d6dfd9efSDavid du Colombier }
139*d6dfd9efSDavid du Colombier 
140*d6dfd9efSDavid du Colombier void
mmurelease(Proc * p)141*d6dfd9efSDavid du Colombier mmurelease(Proc* p)
142*d6dfd9efSDavid du Colombier {
143*d6dfd9efSDavid du Colombier 	p->mmupid = 0;
144*d6dfd9efSDavid du Colombier 	putpid(0);
145*d6dfd9efSDavid du Colombier }
146*d6dfd9efSDavid du Colombier 
147*d6dfd9efSDavid du Colombier void
putmmu(uintptr va,uintptr pa,Page * page)148*d6dfd9efSDavid du Colombier putmmu(uintptr va, uintptr pa, Page* page)
149*d6dfd9efSDavid du Colombier {
150*d6dfd9efSDavid du Colombier 	int x, s, tp;
151*d6dfd9efSDavid du Colombier 	char *ctl;
152*d6dfd9efSDavid du Colombier 	u32int tlbhi, tlblo;
153*d6dfd9efSDavid du Colombier 
154*d6dfd9efSDavid du Colombier 	if(va >= KZERO)
155*d6dfd9efSDavid du Colombier 		panic("mmuput");
156*d6dfd9efSDavid du Colombier 
157*d6dfd9efSDavid du Colombier 	tlbhi = TLBEPN(va) | TLB4K | TLBVALID;
158*d6dfd9efSDavid du Colombier 	tlblo = TLBRPN(pa) | TLBEX | TLBZONE(1);	/* user page */
159*d6dfd9efSDavid du Colombier 	if(pa & PTEWRITE)
160*d6dfd9efSDavid du Colombier 		tlblo |= TLBWR;
161*d6dfd9efSDavid du Colombier 	/* must not set TLBG on instruction pages */
162*d6dfd9efSDavid du Colombier 	if(pa & PTEUNCACHED)
163*d6dfd9efSDavid du Colombier 		tlblo |= TLBI;
164*d6dfd9efSDavid du Colombier 	/* else use write-back cache; write-through would need TLBW set */
165*d6dfd9efSDavid du Colombier 
166*d6dfd9efSDavid du Colombier 	s = splhi();
167*d6dfd9efSDavid du Colombier 	tp = up->mmupid;
168*d6dfd9efSDavid du Colombier 	if(tp == 0){
169*d6dfd9efSDavid du Colombier 		if(up->kp)
170*d6dfd9efSDavid du Colombier 			panic("mmuput kp");
171*d6dfd9efSDavid du Colombier 		tp = newtlbpid(up);
172*d6dfd9efSDavid du Colombier 		putpid(tp);
173*d6dfd9efSDavid du Colombier 	}else if(getpid() != tp)
174*d6dfd9efSDavid du Colombier 		panic("mmuput pid %#ux %#ux", tp, getpid());
175*d6dfd9efSDavid du Colombier 
176*d6dfd9efSDavid du Colombier 	/* see if it's already there: note that tlbsx[cc] uses current PID */
177*d6dfd9efSDavid du Colombier 	x = tlbsxcc(va);
178*d6dfd9efSDavid du Colombier 	if(x < 0){
179*d6dfd9efSDavid du Colombier 		if(m->utlbnext > m->utlbhi)
180*d6dfd9efSDavid du Colombier 			m->utlbnext = 0;
181*d6dfd9efSDavid du Colombier 		x = m->utlbnext++;
182*d6dfd9efSDavid du Colombier 	}else if(x > m->utlbhi)		/* shouldn't touch kernel entries */
183*d6dfd9efSDavid du Colombier 		panic("mmuput index va=%#p x=%d klo=%d", va, x, m->utlbhi);
184*d6dfd9efSDavid du Colombier 	if(DEBUG)
185*d6dfd9efSDavid du Colombier 		iprint("put %#p %#p-> %d: %#ux %8.8ux\n", va, pa, x, tlbhi, tlblo);
186*d6dfd9efSDavid du Colombier 	barriers(); sync(); isync();
187*d6dfd9efSDavid du Colombier 	tlbwrx(x, tlbhi, tlblo);
188*d6dfd9efSDavid du Colombier 	putstlb(tp, TLBEPN(va), tlblo);
189*d6dfd9efSDavid du Colombier 	barriers(); sync(); isync();
190*d6dfd9efSDavid du Colombier 	/* verify that tlb entry was written into the tlb okay */
191*d6dfd9efSDavid du Colombier 	if (tlbsxcc(va) < 0)
192*d6dfd9efSDavid du Colombier 		panic("tlb entry for va %#lux written into but not received by tlb",
193*d6dfd9efSDavid du Colombier 			va);
194*d6dfd9efSDavid du Colombier 	splx(s);
195*d6dfd9efSDavid du Colombier 
196*d6dfd9efSDavid du Colombier 	ctl = &page->cachectl[m->machno];
197*d6dfd9efSDavid du Colombier 	switch(*ctl){
198*d6dfd9efSDavid du Colombier 	case PG_TXTFLUSH:
199*d6dfd9efSDavid du Colombier 		dcflush(page->va, BY2PG);
200*d6dfd9efSDavid du Colombier 		icflush(page->va, BY2PG);
201*d6dfd9efSDavid du Colombier 		*ctl = PG_NOFLUSH;
202*d6dfd9efSDavid du Colombier 		break;
203*d6dfd9efSDavid du Colombier 	case PG_DATFLUSH:
204*d6dfd9efSDavid du Colombier 		dcflush(page->va, BY2PG);
205*d6dfd9efSDavid du Colombier 		*ctl = PG_NOFLUSH;
206*d6dfd9efSDavid du Colombier 		break;
207*d6dfd9efSDavid du Colombier 	case PG_NEWCOL:
208*d6dfd9efSDavid du Colombier //		cleancache();	/* expensive, but fortunately not needed here */
209*d6dfd9efSDavid du Colombier 		*ctl = PG_NOFLUSH;
210*d6dfd9efSDavid du Colombier 		break;
211*d6dfd9efSDavid du Colombier 	}
212*d6dfd9efSDavid du Colombier }
213*d6dfd9efSDavid du Colombier 
214*d6dfd9efSDavid du Colombier /*
215*d6dfd9efSDavid du Colombier  * Process must be splhi
216*d6dfd9efSDavid du Colombier  */
217*d6dfd9efSDavid du Colombier static int
newtlbpid(Proc * p)218*d6dfd9efSDavid du Colombier newtlbpid(Proc *p)
219*d6dfd9efSDavid du Colombier {
220*d6dfd9efSDavid du Colombier 	int i, s;
221*d6dfd9efSDavid du Colombier 	Proc **h;
222*d6dfd9efSDavid du Colombier 
223*d6dfd9efSDavid du Colombier 	i = m->lastpid;
224*d6dfd9efSDavid du Colombier 	h = m->pidproc;
225*d6dfd9efSDavid du Colombier 	for(s = 0; s < NTLBPID; s++) {
226*d6dfd9efSDavid du Colombier 		i++;
227*d6dfd9efSDavid du Colombier 		if(i >= NTLBPID)
228*d6dfd9efSDavid du Colombier 			i = 1;
229*d6dfd9efSDavid du Colombier 		if(h[i] == nil)
230*d6dfd9efSDavid du Colombier 			break;
231*d6dfd9efSDavid du Colombier 	}
232*d6dfd9efSDavid du Colombier 
233*d6dfd9efSDavid du Colombier 	if(h[i] != nil){
234*d6dfd9efSDavid du Colombier 		purgetlb(i);
235*d6dfd9efSDavid du Colombier 		if(h[i] != nil)
236*d6dfd9efSDavid du Colombier 			panic("newtlb");
237*d6dfd9efSDavid du Colombier 	}
238*d6dfd9efSDavid du Colombier 
239*d6dfd9efSDavid du Colombier 	m->pidproc[i] = p;
240*d6dfd9efSDavid du Colombier 	p->mmupid = i;
241*d6dfd9efSDavid du Colombier 	m->lastpid = i;
242*d6dfd9efSDavid du Colombier 
243*d6dfd9efSDavid du Colombier 	return i;
244*d6dfd9efSDavid du Colombier }
245*d6dfd9efSDavid du Colombier 
246*d6dfd9efSDavid du Colombier static void
purgetlb(int pid)247*d6dfd9efSDavid du Colombier purgetlb(int pid)
248*d6dfd9efSDavid du Colombier {
249*d6dfd9efSDavid du Colombier 	int i, p;
250*d6dfd9efSDavid du Colombier 	Proc *sp, **pidproc;
251*d6dfd9efSDavid du Colombier 	Softtlb *entry, *etab;
252*d6dfd9efSDavid du Colombier 	u32int hi;
253*d6dfd9efSDavid du Colombier 
254*d6dfd9efSDavid du Colombier 	m->tlbpurge++;
255*d6dfd9efSDavid du Colombier 
256*d6dfd9efSDavid du Colombier 	/*
257*d6dfd9efSDavid du Colombier 	 * find all pid entries that are no longer used by processes
258*d6dfd9efSDavid du Colombier 	 */
259*d6dfd9efSDavid du Colombier 	pidproc = m->pidproc;
260*d6dfd9efSDavid du Colombier 	for(i=1; i<NTLBPID; i++) {
261*d6dfd9efSDavid du Colombier 		sp = pidproc[i];
262*d6dfd9efSDavid du Colombier 		if(sp != nil && sp->mmupid != i)
263*d6dfd9efSDavid du Colombier 			pidproc[i] = nil;
264*d6dfd9efSDavid du Colombier 	}
265*d6dfd9efSDavid du Colombier 
266*d6dfd9efSDavid du Colombier 	/*
267*d6dfd9efSDavid du Colombier 	 * shoot down the one we want
268*d6dfd9efSDavid du Colombier 	 */
269*d6dfd9efSDavid du Colombier 	sp = pidproc[pid];
270*d6dfd9efSDavid du Colombier 	if(sp != nil)
271*d6dfd9efSDavid du Colombier 		sp->mmupid = 0;
272*d6dfd9efSDavid du Colombier 	pidproc[pid] = nil;
273*d6dfd9efSDavid du Colombier 
274*d6dfd9efSDavid du Colombier 	/*
275*d6dfd9efSDavid du Colombier 	 * clean out all dead pids from the stlb;
276*d6dfd9efSDavid du Colombier 	 */
277*d6dfd9efSDavid du Colombier 	entry = m->stlb;
278*d6dfd9efSDavid du Colombier 	for(etab = &entry[STLBSIZE]; entry < etab; entry++)
279*d6dfd9efSDavid du Colombier 		if(pidproc[(entry->hi>>2)&0xFF] == nil){
280*d6dfd9efSDavid du Colombier 			entry->hi = 0;
281*d6dfd9efSDavid du Colombier 			entry->lo = 0;
282*d6dfd9efSDavid du Colombier 		}
283*d6dfd9efSDavid du Colombier 
284*d6dfd9efSDavid du Colombier 	/*
285*d6dfd9efSDavid du Colombier 	 * clean up the hardware
286*d6dfd9efSDavid du Colombier 	 */
287*d6dfd9efSDavid du Colombier 	p = getpid();
288*d6dfd9efSDavid du Colombier 	for(i = 0; i <= m->utlbhi; i++){
289*d6dfd9efSDavid du Colombier 		hi = tlbrehi(i);
290*d6dfd9efSDavid du Colombier 		if(hi & TLBVALID && pidproc[getpid()] == nil)
291*d6dfd9efSDavid du Colombier 			tlbwrx(i, 0, 0);
292*d6dfd9efSDavid du Colombier 	}
293*d6dfd9efSDavid du Colombier 	putpid(p);
294*d6dfd9efSDavid du Colombier }
295*d6dfd9efSDavid du Colombier 
296*d6dfd9efSDavid du Colombier /*
297*d6dfd9efSDavid du Colombier  * return required size and alignment to map n bytes in a tlb entry
298*d6dfd9efSDavid du Colombier  */
299*d6dfd9efSDavid du Colombier ulong
mmumapsize(ulong n)300*d6dfd9efSDavid du Colombier mmumapsize(ulong n)
301*d6dfd9efSDavid du Colombier {
302*d6dfd9efSDavid du Colombier 	ulong size;
303*d6dfd9efSDavid du Colombier 	int i;
304*d6dfd9efSDavid du Colombier 
305*d6dfd9efSDavid du Colombier 	size = 1024;
306*d6dfd9efSDavid du Colombier 	for(i = 0; i < 8 && size < n; i++)
307*d6dfd9efSDavid du Colombier 		size <<= 2;
308*d6dfd9efSDavid du Colombier 	return size;
309*d6dfd9efSDavid du Colombier }
310*d6dfd9efSDavid du Colombier 
311*d6dfd9efSDavid du Colombier /*
312*d6dfd9efSDavid du Colombier  * map a physical addresses at pa to va, with the given attributes.
313*d6dfd9efSDavid du Colombier  * the virtual address must not be mapped already.
314*d6dfd9efSDavid du Colombier  * if va is nil, map it at pa in virtual space.
315*d6dfd9efSDavid du Colombier  */
316*d6dfd9efSDavid du Colombier void*
kmapphys(uintptr va,uintptr pa,ulong nb,ulong attr,ulong le)317*d6dfd9efSDavid du Colombier kmapphys(uintptr va, uintptr pa, ulong nb, ulong attr, ulong le)
318*d6dfd9efSDavid du Colombier {
319*d6dfd9efSDavid du Colombier 	int s, i, p;
320*d6dfd9efSDavid du Colombier 	ulong size;
321*d6dfd9efSDavid du Colombier 
322*d6dfd9efSDavid du Colombier 	if(va == 0)
323*d6dfd9efSDavid du Colombier 		va = pa;	/* simplest is to use a 1-1 map */
324*d6dfd9efSDavid du Colombier 	size = 1024;
325*d6dfd9efSDavid du Colombier 	for(i = 0; i < 8 && size < nb; i++)
326*d6dfd9efSDavid du Colombier 		size <<= 2;
327*d6dfd9efSDavid du Colombier 	if(i >= 8)
328*d6dfd9efSDavid du Colombier 		return 0;
329*d6dfd9efSDavid du Colombier 	if(m->utlbhi <= Minutlb)
330*d6dfd9efSDavid du Colombier 		panic("kmapphys");
331*d6dfd9efSDavid du Colombier 	s = splhi();
332*d6dfd9efSDavid du Colombier 	p = getpid();
333*d6dfd9efSDavid du Colombier 	putpid(0);
334*d6dfd9efSDavid du Colombier 	tlbwrx(m->utlbhi, va | (i<<7) | TLBVALID | le, pa | TLBZONE(0) | attr);
335*d6dfd9efSDavid du Colombier 	m->utlbhi--;
336*d6dfd9efSDavid du Colombier 	putpid(p);
337*d6dfd9efSDavid du Colombier 	splx(s);
338*d6dfd9efSDavid du Colombier 	if(DEBUG)
339*d6dfd9efSDavid du Colombier 		tlbdump("kmapphys");
340*d6dfd9efSDavid du Colombier 
341*d6dfd9efSDavid du Colombier 	return UINT2PTR(va);
342*d6dfd9efSDavid du Colombier }
343*d6dfd9efSDavid du Colombier 
344*d6dfd9efSDavid du Colombier /*
345*d6dfd9efSDavid du Colombier  * return an uncached alias for the memory at a
346*d6dfd9efSDavid du Colombier  * (unused)
347*d6dfd9efSDavid du Colombier void*
348*d6dfd9efSDavid du Colombier mmucacheinhib(void* a, ulong nb)
349*d6dfd9efSDavid du Colombier {
350*d6dfd9efSDavid du Colombier 	uintptr pa;
351*d6dfd9efSDavid du Colombier 
352*d6dfd9efSDavid du Colombier 	if(a == nil)
353*d6dfd9efSDavid du Colombier 		return nil;
354*d6dfd9efSDavid du Colombier 	dcflush(PTR2UINT(a), nb);
355*d6dfd9efSDavid du Colombier 	pa = PADDR(a);
356*d6dfd9efSDavid du Colombier 	return kmapphys(KSEG1|pa, pa, nb, TLBWR | TLBI | TLBG, 0);
357*d6dfd9efSDavid du Colombier }
358*d6dfd9efSDavid du Colombier  */
359*d6dfd9efSDavid du Colombier 
360*d6dfd9efSDavid du Colombier static void
putstlb(int pid,u32int va,u32int tlblo)361*d6dfd9efSDavid du Colombier putstlb(int pid, u32int va, u32int tlblo)
362*d6dfd9efSDavid du Colombier {
363*d6dfd9efSDavid du Colombier 	Softtlb *entry;
364*d6dfd9efSDavid du Colombier 
365*d6dfd9efSDavid du Colombier 	pid <<= 2;
366*d6dfd9efSDavid du Colombier 	entry = &m->stlb[((va>>12)^pid)&(STLBSIZE-1)];
367*d6dfd9efSDavid du Colombier 	entry->hi = va | pid;
368*d6dfd9efSDavid du Colombier 	entry->lo = tlblo;
369*d6dfd9efSDavid du Colombier }
370*d6dfd9efSDavid du Colombier 
371*d6dfd9efSDavid du Colombier /*
372*d6dfd9efSDavid du Colombier  * Return the number of bytes that can be accessed via KADDR(pa).
373*d6dfd9efSDavid du Colombier  * If pa is not a valid argument to KADDR, return 0.
374*d6dfd9efSDavid du Colombier  */
375*d6dfd9efSDavid du Colombier uintptr
cankaddr(uintptr pa)376*d6dfd9efSDavid du Colombier cankaddr(uintptr pa)
377*d6dfd9efSDavid du Colombier {
378*d6dfd9efSDavid du Colombier 	if( /* pa >= PHYSDRAM && */ pa < PHYSDRAM + 512*MiB)
379*d6dfd9efSDavid du Colombier 		return PHYSDRAM + 512*MiB - pa;
380*d6dfd9efSDavid du Colombier 	return 0;
381*d6dfd9efSDavid du Colombier }
382