BSD 4_2 development
[unix-history] / usr / src / sys / vax / mem.c
CommitLineData
61c578c4
C
1/* mem.c 6.1 83/07/29 */
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 "../vax/mtpr.h"
20
21mmread(dev, uio)
22 dev_t dev;
23 struct uio *uio;
24{
25
26 return (mmrw(dev, uio, UIO_READ));
27}
28
29mmwrite(dev, uio)
30 dev_t dev;
31 struct uio *uio;
32{
33
34 return (mmrw(dev, uio, UIO_WRITE));
35}
36
37mmrw(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 int umbabeg, umbaend;
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 = min((u_int)(NBPG - o), (u_int)iov->iov_len);
70 c = min(c, (u_int)(NBPG - ((int)iov->iov_base&PGOFSET)));
71 error = uiomove((caddr_t)&vmmap[o], (int)c, rw, uio);
72 continue;
73
74/* minor device 1 is kernel memory */
75 case 1:
76 if ((caddr_t)uio->uio_offset < (caddr_t)&umbabeg &&
77 (caddr_t)uio->uio_offset + uio->uio_resid >= (caddr_t)&umbabeg)
78 goto fault;
79 if ((caddr_t)uio->uio_offset >= (caddr_t)&umbabeg &&
80 (caddr_t)uio->uio_offset < (caddr_t)&umbaend)
81 goto fault;
82 c = iov->iov_len;
83 if (!kernacc((caddr_t)uio->uio_offset, c, rw == UIO_READ ? B_READ : B_WRITE))
84 goto fault;
85 error = uiomove((caddr_t)uio->uio_offset, (int)c, rw, uio);
86 continue;
87
88/* minor device 2 is EOF/RATHOLE */
89 case 2:
90 if (rw == UIO_READ)
91 return (0);
92 c = iov->iov_len;
93 break;
94
95/* minor device 3 is unibus memory (addressed by shorts) */
96 case 3:
97 c = iov->iov_len;
98 if (!kernacc((caddr_t)uio->uio_offset, c, rw == UIO_READ ? B_READ : B_WRITE))
99 goto fault;
100 if (!useracc(iov->iov_base, c, rw == UIO_READ ? B_WRITE : B_READ))
101 goto fault;
102 error = UNIcpy((caddr_t)uio->uio_offset, iov->iov_base,
103 (int)c, rw);
104 break;
105 }
106 if (error)
107 break;
108 iov->iov_base += c;
109 iov->iov_len -= c;
110 uio->uio_offset += c;
111 uio->uio_resid -= c;
112 }
113 return (error);
114fault:
115 return (EFAULT);
116}
117
118/*
119 * UNIBUS Address Space <--> User Space transfer
120 */
121UNIcpy(uniadd, usradd, n, rw)
122 caddr_t uniadd, usradd;
123 register int n;
124 enum uio_rw rw;
125{
126 register short *from, *to;
127
128 if (rw == UIO_READ) {
129 from = (short *)uniadd;
130 to = (short *)usradd;
131 } else {
132 from = (short *)usradd;
133 to = (short *)uniadd;
134 }
135 for (n >>= 1; n > 0; n--)
136 *to++ = *from++;
137 return (0);
138}