xref: /original-bsd/sys/vax/vax/mem.c (revision d25e1985)
1 /*	mem.c	3.4	06/07/80	*/
2 
3 /*
4  * Memory special file
5  *	minor device 0 is physical memory
6  *	minor device 1 is kernel memory
7  *	minor device 2 is EOF/RATHOLE
8  *	minor device 3 is unibus memory (addressed by shorts)
9  */
10 
11 #include "../h/param.h"
12 #include "../h/dir.h"
13 #include "../h/user.h"
14 #include "../h/conf.h"
15 #include "../h/buf.h"
16 #include "../h/systm.h"
17 #include "../h/pte.h"
18 #include "../h/mtpr.h"
19 #include "../h/vm.h"
20 #include "../h/cmap.h"
21 
22 mmread(dev)
23 {
24 	register int o;
25 	register unsigned c, v;
26 
27 	switch (minor(dev)) {
28 
29 	case 0:
30 		while (u.u_count != 0 && u.u_error == 0) {
31 			if (fubyte(u.u_base) == -1)
32 				goto fault;
33 			v = btop(u.u_offset);
34 			if (v >= physmem)
35 				goto fault;
36 			*(int *)mmap = v | (PG_V | PG_KR);
37 			mtpr(TBIS, vmmap);
38 			o = (int)u.u_offset & PGOFSET;
39 			c = min((unsigned)(NBPG - o), u.u_count);
40 			c = min(c, (unsigned)(NBPG - ((int)u.u_base&PGOFSET)));
41 			if (copyout((caddr_t)&vmmap[o], u.u_base, c))
42 				goto fault;
43 			u.u_count -= c;
44 			u.u_base += c;
45 			u.u_offset += c;
46 		}
47 		return;
48 
49 	case 1:
50 		if (u.u_uid != 0) {
51 			if ((caddr_t)u.u_offset < (caddr_t)&umbabeg &&
52 			    (caddr_t)u.u_offset + u.u_count >= (caddr_t)&umbabeg)
53 				goto fault;
54 			if ((caddr_t)u.u_offset >= (caddr_t)&umbabeg &&
55 			    (caddr_t)u.u_offset < (caddr_t)&umbaend)
56 				goto fault;
57 		}
58 		if (!kernacc((caddr_t)u.u_offset, u.u_count, B_READ))
59 			goto fault;
60 		if (copyout((caddr_t)u.u_offset, u.u_base, u.u_count))
61 			goto fault;
62 		c = u.u_count;
63 		u.u_count = 0;
64 		u.u_base += c;
65 		u.u_offset += c;
66 		return;
67 
68 	case 2:
69 		return;
70 
71 	case 3:
72 		if (!kernacc((caddr_t)u.u_offset, u.u_count, B_READ))
73 			goto fault;
74 		if (!useracc(u.u_base, u.u_count, B_WRITE))
75 			goto fault;
76 		UNIcpy((caddr_t)u.u_offset, u.u_base, u.u_count, B_READ);
77 		c = u.u_count;
78 		u.u_count = 0;
79 		u.u_base += c;
80 		u.u_offset += c;
81 		return;
82 	}
83 fault:
84 	u.u_error = EFAULT;
85 	return;
86 }
87 
88 mmwrite(dev)
89 {
90 	register int o;
91 	register unsigned c, v;
92 
93 	switch (minor(dev)) {
94 
95 	case 0:
96 		while (u.u_count != 0 && u.u_error == 0) {
97 			if (fubyte(u.u_base) == -1)
98 				goto fault;
99 			v = btop(u.u_offset);
100 			if (v >= physmem)
101 				goto fault;
102 			*(int *)mmap = v | (PG_V | PG_KW);
103 			mtpr(TBIS, vmmap);
104 			o = (int)u.u_offset & PGOFSET;
105 			c = min((unsigned)(NBPG - o), u.u_count);
106 			c = min(c, (unsigned)(NBPG - ((int)u.u_base&PGOFSET)));
107 			if (copyin(u.u_base, (caddr_t)&vmmap[o], c))
108 				goto fault;
109 			u.u_count -= c;
110 			u.u_base += c;
111 			u.u_offset += c;
112 		}
113 		return;
114 
115 	case 1:
116 		if (!kernacc((caddr_t)u.u_offset, u.u_count, B_WRITE))
117 			goto fault;
118 		if (copyin(u.u_base, (caddr_t)u.u_offset, u.u_count))
119 			goto fault;
120 		u.u_base += u.u_count;
121 		u.u_offset += u.u_count;
122 		u.u_count = 0;
123 		return;
124 
125 	case 2:
126 		u.u_offset += u.u_count;
127 		u.u_count = 0;
128 		return;
129 
130 	case 3:
131 		if (!kernacc((caddr_t)u.u_offset, u.u_count, B_WRITE))
132 			goto fault;
133 		if (!useracc(u.u_base, u.u_count, B_READ))
134 			goto fault;
135 		UNIcpy((caddr_t)u.u_offset, u.u_base, u.u_count, B_WRITE);
136 		u.u_base += u.u_count;
137 		u.u_offset += u.u_count;
138 		u.u_count = 0;
139 		return;
140 	}
141 fault:
142 	u.u_error = EFAULT;
143 	return;
144 }
145 
146 /*
147  * UNIBUS Address Space <--> User Space transfer
148  */
149 UNIcpy(uniadd, usradd, bknt, direct)
150 	caddr_t uniadd, usradd;
151 	unsigned bknt;
152 {
153 	register short *from, *to;
154 	register int i;
155 
156 	if (direct == B_READ) {
157 		from = (short *) uniadd;
158 		to = (short *) usradd;
159 	} else {
160 		from = (short *) usradd;
161 		to = (short *) uniadd;
162 	}
163 	for (i = (bknt>>1); i > 0; i--)
164 		*to++ = *from++;
165 }
166