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