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