xref: /original-bsd/sys/i386/i386/mem.c (revision 4b3fb397)
1 /*	mem.c	1.4	86/12/15	*/
2 
3 /*
4  * Memory special file
5  */
6 
7 #include "../machine/pte.h"
8 
9 #include "../h/param.h"
10 #include "../h/dir.h"
11 #include "../h/user.h"
12 #include "../h/conf.h"
13 #include "../h/buf.h"
14 #include "../h/systm.h"
15 #include "../h/vm.h"
16 #include "../h/cmap.h"
17 #include "../h/uio.h"
18 
19 #include "../tahoe/mtpr.h"
20 
21 mmread(dev, uio)
22 	dev_t dev;
23 	struct uio *uio;
24 {
25 
26 	return (mmrw(dev, uio, UIO_READ));
27 }
28 
29 mmwrite(dev, uio)
30 	dev_t dev;
31 	struct uio *uio;
32 {
33 
34 	return (mmrw(dev, uio, UIO_WRITE));
35 }
36 
37 mmrw(dev, uio, rw)
38 	dev_t dev;
39 	struct uio *uio;
40 	enum uio_rw rw;
41 {
42 	register int o;
43 	register u_int c, v;
44 	register struct iovec *iov;
45 	int error = 0;
46 	extern caddr_t vmembeg, vmemend;
47 
48 
49 	while (uio->uio_resid > 0 && error == 0) {
50 		iov = uio->uio_iov;
51 		if (iov->iov_len == 0) {
52 			uio->uio_iov++;
53 			uio->uio_iovcnt--;
54 			if (uio->uio_iovcnt < 0)
55 				panic("mmrw");
56 			continue;
57 		}
58 		switch (minor(dev)) {
59 
60 /* minor device 0 is physical memory */
61 		case 0:
62 			v = btop(uio->uio_offset);
63 			if (v >= physmem)
64 				goto fault;
65 			*(int *)mmap = v | PG_V |
66 				(rw == UIO_READ ? PG_KR : PG_KW);
67 			mtpr(TBIS, vmmap);
68 			o = (int)uio->uio_offset & PGOFSET;
69 			c = (u_int)(NBPG - ((int)iov->iov_base & PGOFSET));
70 			c = MIN(c, (u_int)(NBPG - o));
71 			c = MIN(c, (u_int)iov->iov_len);
72 			error = uiomove((caddr_t)&vmmap[o], (int)c, rw, uio);
73 			continue;
74 
75 /* minor device 1 is kernel memory */
76 		case 1:
77 			if ((caddr_t)uio->uio_offset < (caddr_t)&vmembeg &&
78 			    (caddr_t)uio->uio_offset + uio->uio_resid >= (caddr_t)&vmembeg)
79 				goto fault;
80 			if ((caddr_t)uio->uio_offset >= (caddr_t)&vmembeg &&
81 			    (caddr_t)uio->uio_offset < (caddr_t)&vmemend)
82 				goto fault;
83 			c = iov->iov_len;
84 			if (!kernacc((caddr_t)uio->uio_offset, c, rw == UIO_READ ? B_READ : B_WRITE))
85 				goto fault;
86 			error = uiomove((caddr_t)uio->uio_offset, (int)c, rw, uio);
87 			continue;
88 
89 /* minor device 2 is EOF/RATHOLE */
90 		case 2:
91 			if (rw == UIO_READ)
92 				return (0);
93 			c = iov->iov_len;
94 			break;
95 
96 /* minor device 3 is versabus memory (addressed by shorts) */
97 		case 3:
98 			c = iov->iov_len;
99 			if (!kernacc((caddr_t)uio->uio_offset, c, rw == UIO_READ ? B_READ : B_WRITE))
100 				goto fault;
101 			if (!useracc(iov->iov_base, c, rw == UIO_READ ? B_WRITE : B_READ))
102 				goto fault;
103 			error = VERSAcpy((caddr_t)uio->uio_offset, iov->iov_base,
104 			    (int)c, rw);
105 			break;
106 		}
107 		if (error)
108 			break;
109 		iov->iov_base += c;
110 		iov->iov_len -= c;
111 		uio->uio_offset += c;
112 		uio->uio_resid -= c;
113 	}
114 	return (error);
115 fault:
116 	return (EFAULT);
117 }
118 
119 /*
120  * VERSABUS Address Space <--> User Space transfer
121  */
122 VERSAcpy(versaadd, usradd, n, rw)
123 	caddr_t versaadd, usradd;
124 	register int n;
125 	enum uio_rw rw;
126 {
127 	register short *from, *to;
128 
129 	if(((int)versaadd&1) || ((int)usradd&1))
130 		return (EFAULT);
131 	if (rw == UIO_READ) {
132 		from = (short *)versaadd;
133 		to = (short *)usradd;
134 	} else {
135 		from = (short *)usradd;
136 		to = (short *)versaadd;
137 	}
138 	for (n >>= 1; n > 0; n--)
139 		*to++ = *from++;
140 	return (0);
141 }
142