xref: /original-bsd/sys/i386/i386/mem.c (revision e718337e)
1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * William Jolitz.
7  *
8  * %sccs.include.noredist.c%
9  *
10  *	@(#)mem.c	5.5 (Berkeley) 11/25/90
11  */
12 
13 /*
14  * Memory special file
15  */
16 
17 #include "machine/pte.h"
18 
19 #include "param.h"
20 #include "dir.h"
21 #include "user.h"
22 #include "conf.h"
23 #include "buf.h"
24 #include "systm.h"
25 #include "vm.h"
26 #include "cmap.h"
27 #include "uio.h"
28 
29 mmread(dev, uio)
30 	dev_t dev;
31 	struct uio *uio;
32 {
33 
34 	return (mmrw(dev, uio, UIO_READ));
35 }
36 
37 mmwrite(dev, uio)
38 	dev_t dev;
39 	struct uio *uio;
40 {
41 
42 	return (mmrw(dev, uio, UIO_WRITE));
43 }
44 
45 mmrw(dev, uio, rw)
46 	dev_t dev;
47 	struct uio *uio;
48 	enum uio_rw rw;
49 {
50 	register int o;
51 	register u_int c, v;
52 	register struct iovec *iov;
53 	int error = 0;
54 
55 
56 	while (uio->uio_resid > 0 && error == 0) {
57 		iov = uio->uio_iov;
58 		if (iov->iov_len == 0) {
59 			uio->uio_iov++;
60 			uio->uio_iovcnt--;
61 			if (uio->uio_iovcnt < 0)
62 				panic("mmrw");
63 			continue;
64 		}
65 		switch (minor(dev)) {
66 
67 /* minor device 0 is physical memory */
68 		case 0:
69 			v = btop(uio->uio_offset);
70 			if (v >= physmem)
71 				goto fault;
72 			*(int *)mmap = ctob(v) | PG_V |
73 				(rw == UIO_READ ? PG_KR : PG_KW);
74 			load_cr3(u.u_pcb.pcb_ptd);
75 			o = (int)uio->uio_offset & PGOFSET;
76 			c = (u_int)(NBPG - ((int)iov->iov_base & PGOFSET));
77 			c = MIN(c, (u_int)(NBPG - o));
78 			c = MIN(c, (u_int)iov->iov_len);
79 			error = uiomove((caddr_t)&vmmap[o], (int)c, rw, uio);
80 			continue;
81 
82 /* minor device 1 is kernel memory */
83 		case 1:
84 			c = iov->iov_len;
85 			if (!kernacc((caddr_t)uio->uio_offset, c, rw == UIO_READ ? B_READ : B_WRITE))
86 				goto fault;
87 			error = uiomove((caddr_t)uio->uio_offset, (int)c, rw, uio);
88 			continue;
89 
90 /* minor device 2 is EOF/RATHOLE */
91 		case 2:
92 			if (rw == UIO_READ)
93 				return (0);
94 			c = iov->iov_len;
95 			break;
96 
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