xref: /original-bsd/sys/vax/vax/vm_machdep.c (revision c829ecf6)
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.8 (Berkeley) 06/05/90
7  */
8 
9 #include "param.h"
10 #include "systm.h"
11 #include "user.h"
12 #include "proc.h"
13 #include "cmap.h"
14 #include "vm.h"
15 #include "text.h"
16 
17 #include "pte.h"
18 #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 		u.u_error = EFAULT;
94 		return (0);
95 	}
96 	tp = vtotp(u.u_procp, v);
97 	pte = tptopte(u.u_procp, tp);
98 	if (pte->pg_fod == 0 && pte->pg_pfnum) {
99 		c = &cmap[pgtocm(pte->pg_pfnum)];
100 		if (c->c_blkno)
101 			munhash(c->c_vp, (daddr_t)(u_long)c->c_blkno);
102 	}
103 	*(int *)pte &= ~PG_PROT;
104 	*(int *)pte |= tprot;
105 	distcl(pte);
106 	tbiscl(v);
107 	return (1);
108 }
109 
110 settprot(tprot)
111 	long tprot;
112 {
113 	register int *ptaddr, i;
114 
115 	ptaddr = (int *)mfpr(P0BR);
116 	for (i = 0; i < u.u_tsize; i++) {
117 		ptaddr[i] &= ~PG_PROT;
118 		ptaddr[i] |= tprot;
119 	}
120 	mtpr(TBIA, 0);
121 }
122 
123 /*
124  * Rest are machine-dependent
125  */
126 
127 getmemc(addr)
128 	caddr_t addr;
129 {
130 	register int c;
131 	struct pte savemap;
132 
133 	savemap = mmap[0];
134 	*(int *)mmap = PG_V | PG_KR | btop(addr);
135 	mtpr(TBIS, vmmap);
136 	c = *(char *)&vmmap[(int)addr & PGOFSET];
137 	mmap[0] = savemap;
138 	mtpr(TBIS, vmmap);
139 	return (c & 0377);
140 }
141 
142 putmemc(addr, val)
143 	caddr_t addr;
144 {
145 	struct pte savemap;
146 
147 	savemap = mmap[0];
148 	*(int *)mmap = PG_V | PG_KW | btop(addr);
149 	mtpr(TBIS, vmmap);
150 	*(char *)&vmmap[(int)addr & PGOFSET] = val;
151 	mmap[0] = savemap;
152 	mtpr(TBIS, vmmap);
153 }
154 
155 /*
156  * Move pages from one kernel virtual address to another.
157  * Both addresses are assumed to reside in the Sysmap,
158  * and size must be a multiple of CLSIZE.
159  */
160 pagemove(from, to, size)
161 	register caddr_t from, to;
162 	int size;
163 {
164 	register struct pte *fpte, *tpte;
165 
166 	if (size % CLBYTES)
167 		panic("pagemove");
168 	fpte = kvtopte(from);
169 	tpte = kvtopte(to);
170 	while (size > 0) {
171 		*tpte++ = *fpte;
172 		*(int *)fpte++ = 0;
173 		mtpr(TBIS, from);
174 		mtpr(TBIS, to);
175 		from += NBPG;
176 		to += NBPG;
177 		size -= NBPG;
178 	}
179 }
180