xref: /original-bsd/sys/vax/vax/vm_machdep.c (revision abb30312)
1 /*
2  * Copyright (c) 1982, 1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)vm_machdep.c	7.10 (Berkeley) 12/16/90
7  */
8 
9 #include "sys/param.h"
10 #include "sys/systm.h"
11 #include "sys/user.h"
12 #include "sys/proc.h"
13 #include "sys/cmap.h"
14 #include "sys/vm.h"
15 #include "sys/text.h"
16 
17 #include "../include/pte.h"
18 #include "../include/mtpr.h"
19 
20 /*
21  * Set a red zone in the kernel stack after the u. area.
22  */
23 setredzone(pte, vaddr)
24 	register struct pte *pte;
25 	caddr_t vaddr;
26 {
27 
28 	pte += (sizeof (struct user) + NBPG - 1) / NBPG;
29 	*(int *)pte &= ~PG_PROT;
30 	*(int *)pte |= PG_URKR;
31 	if (vaddr)
32 		mtpr(TBIS, vaddr + sizeof (struct user));
33 }
34 
35 /*
36  * Check for valid program size
37  * NB - Check data and data growth separately as they may overflow
38  * when summed together.
39  */
40 chksize(ts, ids, uds, ss)
41 	unsigned ts, ids, uds, ss;
42 {
43 	extern unsigned maxtsize;
44 
45 	if (ctob(ts) > maxtsize ||
46 	    ctob(ids) > u.u_rlimit[RLIMIT_DATA].rlim_cur ||
47 	    ctob(uds) > u.u_rlimit[RLIMIT_DATA].rlim_cur ||
48 	    ctob(ids + uds) > u.u_rlimit[RLIMIT_DATA].rlim_cur ||
49 	    ctob(ss) > u.u_rlimit[RLIMIT_STACK].rlim_cur) {
50 		return (ENOMEM);
51 	}
52 	return (0);
53 }
54 
55 /*ARGSUSED*/
56 newptes(pte, v, size)
57 	register struct pte *pte;
58 	u_int v;
59 	register int size;
60 {
61 	register caddr_t a = ptob(v);
62 
63 #ifdef lint
64 	pte = pte;
65 #endif
66 	if (size >= 8) {
67 		mtpr(TBIA, 0);
68 		return;
69 	}
70 	while (size > 0) {
71 		mtpr(TBIS, a);
72 		a += NBPG;
73 		size--;
74 	}
75 }
76 
77 /*
78  * Change protection codes of text segment.
79  * Have to flush translation buffer since this
80  * affect virtual memory mapping of current process.
81  */
82 chgprot(addr, tprot)
83 	caddr_t addr;
84 	long tprot;
85 {
86 	unsigned v;
87 	int tp;
88 	register struct pte *pte;
89 	register struct cmap *c;
90 
91 	v = clbase(btop(addr));
92 	if (!isatsv(u.u_procp, v))
93 		return (EFAULT);
94 	tp = vtotp(u.u_procp, v);
95 	pte = tptopte(u.u_procp, tp);
96 	if (pte->pg_fod == 0 && pte->pg_pfnum) {
97 		c = &cmap[pgtocm(pte->pg_pfnum)];
98 		if (c->c_blkno)
99 			munhash(c->c_vp, (daddr_t)(u_long)c->c_blkno);
100 	}
101 	*(int *)pte &= ~PG_PROT;
102 	*(int *)pte |= tprot;
103 	distcl(pte);
104 	tbiscl(v);
105 	return (0);
106 }
107 
108 settprot(tprot)
109 	long tprot;
110 {
111 	register int *ptaddr, i;
112 
113 	ptaddr = (int *)mfpr(P0BR);
114 	for (i = 0; i < u.u_tsize; i++) {
115 		ptaddr[i] &= ~PG_PROT;
116 		ptaddr[i] |= tprot;
117 	}
118 	mtpr(TBIA, 0);
119 }
120 
121 /*
122  * Rest are machine-dependent
123  */
124 
125 getmemc(addr)
126 	caddr_t addr;
127 {
128 	register int c;
129 	struct pte savemap;
130 
131 	savemap = mmap[0];
132 	*(int *)mmap = PG_V | PG_KR | btop(addr);
133 	mtpr(TBIS, vmmap);
134 	c = *(char *)&vmmap[(int)addr & PGOFSET];
135 	mmap[0] = savemap;
136 	mtpr(TBIS, vmmap);
137 	return (c & 0377);
138 }
139 
140 putmemc(addr, val)
141 	caddr_t addr;
142 {
143 	struct pte savemap;
144 
145 	savemap = mmap[0];
146 	*(int *)mmap = PG_V | PG_KW | btop(addr);
147 	mtpr(TBIS, vmmap);
148 	*(char *)&vmmap[(int)addr & PGOFSET] = val;
149 	mmap[0] = savemap;
150 	mtpr(TBIS, vmmap);
151 }
152 
153 /*
154  * Move pages from one kernel virtual address to another.
155  * Both addresses are assumed to reside in the Sysmap,
156  * and size must be a multiple of CLSIZE.
157  */
158 pagemove(from, to, size)
159 	register caddr_t from, to;
160 	int size;
161 {
162 	register struct pte *fpte, *tpte;
163 
164 	if (size % CLBYTES)
165 		panic("pagemove");
166 	fpte = kvtopte(from);
167 	tpte = kvtopte(to);
168 	while (size > 0) {
169 		*tpte++ = *fpte;
170 		*(int *)fpte++ = 0;
171 		mtpr(TBIS, from);
172 		mtpr(TBIS, to);
173 		from += NBPG;
174 		to += NBPG;
175 		size -= NBPG;
176 	}
177 }
178