xref: /original-bsd/sys/vax/vax/vm_machdep.c (revision c43e4352)
1 /*	vm_machdep.c	6.1	83/07/29	*/
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 "../vax/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(TBIS, vaddr + sizeof (struct user));
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(TBIS, ptob(v));
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(TBIA, 0);
114 		return;
115 	}
116 	while (size > 0) {
117 		mtpr(TBIS, a);
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(TBIA, 0);
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(TBIS, vmmap);
183 	c = *(char *)&vmmap[(int)addr & PGOFSET];
184 	mmap[0] = savemap;
185 	mtpr(TBIS, vmmap);
186 	return (c & 0377);
187 }
188 
189 putmemc(addr, val)
190 	caddr_t addr;
191 {
192 	struct pte savemap;
193 
194 	savemap = mmap[0];
195 	*(int *)mmap = PG_V | PG_KW | btop(addr);
196 	mtpr(TBIS, vmmap);
197 	*(char *)&vmmap[(int)addr & PGOFSET] = val;
198 	mmap[0] = savemap;
199 	mtpr(TBIS, vmmap);
200 }
201 
202 /*
203  * Move pages from one kernel virtual address to another.
204  * Both addresses are assumed to reside in the Sysmap,
205  * and size must be a multiple of CLSIZE.
206  */
207 pagemove(from, to, size)
208 	register caddr_t from, to;
209 	int size;
210 {
211 	register struct pte *fpte, *tpte;
212 
213 	if (size % CLBYTES)
214 		panic("pagemove");
215 	fpte = &Sysmap[btop(from - 0x80000000)];
216 	tpte = &Sysmap[btop(to - 0x80000000)];
217 	while (size > 0) {
218 		*tpte++ = *fpte;
219 		*(int *)fpte++ = 0;
220 		mtpr(TBIS, from);
221 		mtpr(TBIS, to);
222 		from += NBPG;
223 		to += NBPG;
224 		size -= NBPG;
225 	}
226 }
227