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