xref: /original-bsd/sys/tahoe/tahoe/vm_machdep.c (revision 0f89e6eb)
1 /*	vm_machdep.c	1.1	85/07/21	*/
2 
3 #include "../machine/pte.h"
4 
5 #include "../h/param.h"
6 #include "../h/systm.h"
7 #include "../h/dir.h"
8 #include "../h/user.h"
9 #include "../h/proc.h"
10 #include "../h/cmap.h"
11 #include "../h/mount.h"
12 #include "../h/vm.h"
13 #include "../h/text.h"
14 
15 #include "../machine/mtpr.h"
16 
17 /*
18  * Set a red zone in the kernel stack after the u. area.
19  */
20 setredzone(pte, vaddr)
21 	register struct pte *pte;
22 	caddr_t vaddr;
23 {
24 
25 	pte += (sizeof (struct user) + NBPG - 1) / NBPG;
26 	*(int *)pte &= ~PG_PROT;
27 	*(int *)pte |= PG_URKR;
28 	if (vaddr)
29 		mtpr(vaddr + sizeof (struct user) + NBPG - 1, TBIS);
30 }
31 
32 #ifndef mapin
33 mapin(pte, v, pfnum, count, prot)
34 	struct pte *pte;
35 	u_int v, pfnum;
36 	int count, prot;
37 {
38 
39 	while (count > 0) {
40 		*(int *)pte++ = pfnum | prot;
41 		mtpr(ptob(v), TBIS);
42 		v++;
43 		pfnum++;
44 		count--;
45 	}
46 }
47 #endif
48 
49 #ifdef notdef
50 /*ARGSUSED*/
51 mapout(pte, size)
52 	register struct pte *pte;
53 	int size;
54 {
55 
56 	panic("mapout");
57 }
58 #endif
59 
60 /*
61  * Check for valid program size
62  */
63 chksize(ts, ds, ss)
64 	register unsigned ts, ds, ss;
65 {
66 	static int maxdmap = 0;
67 
68 	if (ts > MAXTSIZ || ds > MAXDSIZ || ss > MAXSSIZ) {
69 		u.u_error = ENOMEM;
70 		return (1);
71 	}
72 	/* check for swap map overflow */
73 	if (maxdmap == 0) {
74 		register int i, blk;
75 
76 		blk = dmmin;
77 		for (i = 0; i < NDMAP; i++) {
78 			maxdmap += blk;
79 			if (blk < dmmax)
80 				blk *= 2;
81 		}
82 	}
83 	if (ctod(ts) > NXDAD * dmtext ||
84 	    ctod(ds) > maxdmap || ctod(ss) > maxdmap) {
85 		u.u_error = ENOMEM;
86 		return (1);
87 	}
88 	/*
89 	 * Make sure the process isn't bigger than our
90 	 * virtual memory limit.
91 	 *
92 	 * THERE SHOULD BE A CONSTANT FOR THIS.
93 	 */
94 	if (ts + ds + ss + LOWPAGES + HIGHPAGES > btoc(USRSTACK)) {
95 		u.u_error = ENOMEM;
96 		return (1);
97 	}
98 	return (0);
99 }
100 
101 /*ARGSUSED*/
102 newptes(pte, v, size)
103 	register struct pte *pte;
104 	u_int v;
105 	register int size;
106 {
107 	register caddr_t a = ptob(v);
108 
109 #ifdef lint
110 	pte = pte;
111 #endif
112 	if (size >= 8) {
113 		mtpr(0, TBIA);
114 		return;
115 	}
116 	while (size > 0) {
117 		mtpr(a, TBIS);
118 		a += NBPG;
119 		size--;
120 	}
121 }
122 
123 /*
124  * Change protection codes of text segment.
125  * Have to flush translation buffer since this
126  * affect virtual memory mapping of current process.
127  */
128 chgprot(addr, tprot)
129 	caddr_t addr;
130 	long tprot;
131 {
132 	unsigned v;
133 	int tp;
134 	register struct pte *pte;
135 	register struct cmap *c;
136 
137 	v = clbase(btop(addr));
138 	if (!isatsv(u.u_procp, v)) {
139 		u.u_error = EFAULT;
140 		return (0);
141 	}
142 	tp = vtotp(u.u_procp, v);
143 	pte = tptopte(u.u_procp, tp);
144 	if (pte->pg_fod == 0 && pte->pg_pfnum) {
145 		c = &cmap[pgtocm(pte->pg_pfnum)];
146 		if (c->c_blkno && c->c_mdev != MSWAPX)
147 			munhash(mount[c->c_mdev].m_dev,
148 			    (daddr_t)(u_long)c->c_blkno);
149 	}
150 	*(int *)pte &= ~PG_PROT;
151 	*(int *)pte |= tprot;
152 	distcl(pte);
153 	tbiscl(v);
154 	return (1);
155 }
156 
157 settprot(tprot)
158 	long tprot;
159 {
160 	register int *ptaddr, i;
161 
162 	ptaddr = (int *)mfpr(P0BR);
163 	for (i = 0; i < u.u_tsize; i++) {
164 		ptaddr[i] &= ~PG_PROT;
165 		ptaddr[i] |= tprot;
166 	}
167 	mtpr(0, TBIA);
168 }
169 
170 /*
171  * Rest are machine-dependent
172  */
173 
174 getmemc(addr)
175 	caddr_t addr;
176 {
177 	register int c;
178 	struct pte savemap;
179 
180 	savemap = mmap[0];
181 	*(int *)mmap = PG_V | PG_KR | btop(addr);
182 	mtpr(vmmap, TBIS);
183 	uncache (&vmmap[(int)addr & PGOFSET]);
184 	c = *(char *)&vmmap[(int)addr & PGOFSET];
185 	mmap[0] = savemap;
186 	mtpr(vmmap, TBIS);
187 	return (c & 0377);
188 }
189 
190 putmemc(addr, val)
191 	caddr_t addr;
192 {
193 	struct pte savemap;
194 
195 	savemap = mmap[0];
196 	*(int *)mmap = PG_V | PG_KW | btop(addr);
197 	mtpr(vmmap, TBIS);
198 	*(char *)&vmmap[(int)addr & PGOFSET] = val;
199 
200 	mtpr (0, PADC);
201 	mtpr (0, PACC);
202 
203 	mmap[0] = savemap;
204 	mtpr(vmmap, TBIS);
205 }
206 
207 /*
208  * Move pages from one kernel virtual address to another.
209  * Both addresses are assumed to reside in the Sysmap,
210  * and size must be a multiple of CLSIZE.
211  */
212 pagemove(from, to, size)
213 	register caddr_t from, to;
214 	int size;
215 {
216 	register struct pte *fpte, *tpte;
217 
218 	if (size % CLBYTES)
219 		panic("pagemove");
220 	fpte = &Sysmap[btop(from - 0xC0000000)];
221 	tpte = &Sysmap[btop(to - 0xC0000000)];
222 	while (size > 0) {
223 		*tpte++ = *fpte;
224 		*(int *)fpte++ = 0;
225 		mtpr(from, TBIS);
226 		mtpr(to, TBIS);
227 		mtpr(to, P1DC);		/* purge !! */
228 		from += NBPG;
229 		to += NBPG;
230 		size -= NBPG;
231 	}
232 }
233 
234 #ifndef GLOBKEY
235 ckeyrelease(key)
236 /*
237  * release code key
238  */
239 {
240 	register int ipl,i,j ;
241 	ipl = spl8();
242 	if (--ckey_cnt[key-1] < 0 ) {
243 /*
244 		panic ("Code key release");
245 */
246 		printf("Ckey release, key=%d\n", key);
247 		ckey_cnt[key-1] = 0;
248 		splx(ipl);
249 	}
250 	splx(ipl);
251 }
252 
253 
254 dkeyrelease(key)
255 /*
256  * release data key
257  */
258 {
259 	if (--dkey_cnt[key-1] != 0 ) panic ("Data key release");
260 }
261 
262 
263 int
264 getcodekey()
265 /*
266  * Get a code key
267  */
268 {
269 	register int i, ipl, first;
270 
271 	first = 1;
272 	ipl = spl8();
273 retry:
274 	for (i=0; i<255; i++) {
275 		if ( (int)ckey_cache[i] == 0) {
276 			ckey_cache[i] = 1;
277 			ckey_cnt[i] = 1;
278 			splx(ipl);
279 			return (i+1);
280 		};
281 	}
282 	if ( !first) {
283 		splx(ipl);
284 		panic ("Not enough code keys\n");
285 	}
286 	mtpr (0, PACC);
287 	first = 0;
288 	for (i=0; i<255; i++)
289 		if ( ckey_cnt[i] > 0 ) ckey_cache[i] = 1;
290 		else ckey_cache[i] = 0;
291 	goto retry;
292 }
293 
294 int
295 getdatakey()
296 /*
297  * Get a data key
298  */
299 {
300 	register int i, ipl, first;
301 
302 	first = 1;
303 	ipl = spl8();
304 retry:
305 	for (i=0; i<255; i++)
306 		if ( (int)dkey_cache[i] == 0) {
307 			dkey_cache[i] = 1;
308 			dkey_cnt[i] = 1;
309 			splx(ipl);
310 			return (i+1);
311 		};
312 	if ( !first) {
313 		splx(ipl);
314 		panic("Not enough data keys\n");
315 	}
316 	mtpr (0, PADC);
317 	first = 0;
318 	for (i=0; i<255; i++)
319 		if ( dkey_cnt[i] > 0 ) dkey_cache[i] = 1;
320 		else dkey_cache[i] = 0;
321 	goto retry;
322 }
323 #endif
324 
325 /* General (includes system) virtual address to physical */
326 vtoph(p, v)
327 register struct proc *p;
328 register unsigned v;
329 {
330 	register struct pte *thispte;
331 
332 	thispte = vtopte (p, btop(v));
333 	return ( (thispte->pg_pfnum << PGSHIFT) + (v & PGOFSET));
334 }
335 
336