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