xref: /original-bsd/sys/vax/vax/mem.c (revision 6c57d260)
1 /*	mem.c	4.3	81/03/09	*/
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 ((caddr_t)u.u_offset < (caddr_t)&umbabeg &&
51 		    (caddr_t)u.u_offset + u.u_count >= (caddr_t)&umbabeg)
52 			goto fault;
53 		if ((caddr_t)u.u_offset >= (caddr_t)&umbabeg &&
54 		    (caddr_t)u.u_offset < (caddr_t)&umbaend)
55 			goto fault;
56 		if (!kernacc((caddr_t)u.u_offset, u.u_count, B_READ))
57 			goto fault;
58 		if (copyout((caddr_t)u.u_offset, u.u_base, u.u_count))
59 			goto fault;
60 		c = u.u_count;
61 		u.u_count = 0;
62 		u.u_base += c;
63 		u.u_offset += c;
64 		return;
65 
66 	case 2:
67 		return;
68 
69 	case 3:
70 		if (!kernacc((caddr_t)u.u_offset, u.u_count, B_READ))
71 			goto fault;
72 		if (!useracc(u.u_base, u.u_count, B_WRITE))
73 			goto fault;
74 		UNIcpy((caddr_t)u.u_offset, u.u_base, u.u_count, B_READ);
75 		c = u.u_count;
76 		u.u_count = 0;
77 		u.u_base += c;
78 		u.u_offset += c;
79 		return;
80 	}
81 fault:
82 	u.u_error = EFAULT;
83 	return;
84 }
85 
86 mmwrite(dev)
87 {
88 	register int o;
89 	register unsigned c, v;
90 
91 	switch (minor(dev)) {
92 
93 	case 0:
94 		while (u.u_count != 0 && u.u_error == 0) {
95 			if (fubyte(u.u_base) == -1)
96 				goto fault;
97 			v = btop(u.u_offset);
98 			if (v >= physmem)
99 				goto fault;
100 			*(int *)mmap = v | (PG_V | PG_KW);
101 			mtpr(TBIS, vmmap);
102 			o = (int)u.u_offset & PGOFSET;
103 			c = min((unsigned)(NBPG - o), u.u_count);
104 			c = min(c, (unsigned)(NBPG - ((int)u.u_base&PGOFSET)));
105 			if (copyin(u.u_base, (caddr_t)&vmmap[o], c))
106 				goto fault;
107 			u.u_count -= c;
108 			u.u_base += c;
109 			u.u_offset += c;
110 		}
111 		return;
112 
113 	case 1:
114 		if (!kernacc((caddr_t)u.u_offset, u.u_count, B_WRITE))
115 			goto fault;
116 		if (copyin(u.u_base, (caddr_t)u.u_offset, u.u_count))
117 			goto fault;
118 		u.u_base += u.u_count;
119 		u.u_offset += u.u_count;
120 		u.u_count = 0;
121 		return;
122 
123 	case 2:
124 		u.u_offset += u.u_count;
125 		u.u_count = 0;
126 		return;
127 
128 	case 3:
129 		if (!kernacc((caddr_t)u.u_offset, u.u_count, B_WRITE))
130 			goto fault;
131 		if (!useracc(u.u_base, u.u_count, B_READ))
132 			goto fault;
133 		UNIcpy((caddr_t)u.u_offset, u.u_base, u.u_count, B_WRITE);
134 		u.u_base += u.u_count;
135 		u.u_offset += u.u_count;
136 		u.u_count = 0;
137 		return;
138 	}
139 fault:
140 	u.u_error = EFAULT;
141 	return;
142 }
143 
144 /*
145  * UNIBUS Address Space <--> User Space transfer
146  */
147 UNIcpy(uniadd, usradd, bknt, direct)
148 	caddr_t uniadd, usradd;
149 	unsigned bknt;
150 {
151 	register short *from, *to;
152 	register int i;
153 
154 	if (direct == B_READ) {
155 		from = (short *) uniadd;
156 		to = (short *) usradd;
157 	} else {
158 		from = (short *) usradd;
159 		to = (short *) uniadd;
160 	}
161 	for (i = (bknt>>1); i > 0; i--)
162 		*to++ = *from++;
163 }
164