1 /* $OpenBSD: mem.c,v 1.15 2024/12/30 02:46:00 guenther Exp $ */
2 /* $NetBSD: mem.c,v 1.21 2006/07/23 22:06:07 ad Exp $ */
3
4 /*
5 * Copyright (c) 2002 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 * Copyright (c) 1982, 1986, 1990, 1993
8 * The Regents of the University of California. All rights reserved.
9 *
10 * This code is derived from software contributed to Berkeley by
11 * the Systems Programming Group of the University of Utah Computer
12 * Science Department.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 * 3. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)mem.c 8.3 (Berkeley) 1/12/94
39 */
40
41 /*
42 * Copyright (c) 1988 University of Utah.
43 *
44 * This code is derived from software contributed to Berkeley by
45 * the Systems Programming Group of the University of Utah Computer
46 * Science Department.
47 *
48 * Redistribution and use in source and binary forms, with or without
49 * modification, are permitted provided that the following conditions
50 * are met:
51 * 1. Redistributions of source code must retain the above copyright
52 * notice, this list of conditions and the following disclaimer.
53 * 2. Redistributions in binary form must reproduce the above copyright
54 * notice, this list of conditions and the following disclaimer in the
55 * documentation and/or other materials provided with the distribution.
56 * 3. All advertising materials mentioning features or use of this software
57 * must display the following acknowledgement:
58 * This product includes software developed by the University of
59 * California, Berkeley and its contributors.
60 * 4. Neither the name of the University nor the names of its contributors
61 * may be used to endorse or promote products derived from this software
62 * without specific prior written permission.
63 *
64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74 * SUCH DAMAGE.
75 *
76 * @(#)mem.c 8.3 (Berkeley) 1/12/94
77 */
78
79 /*
80 * Memory special file
81 */
82
83 #include <sys/param.h>
84 #include <sys/systm.h>
85 #include <sys/buf.h>
86 #include <sys/filio.h>
87 #include <sys/uio.h>
88 #include <sys/malloc.h>
89 #include <sys/proc.h>
90 #include <sys/conf.h>
91 #include <sys/atomic.h>
92
93 #include <uvm/uvm_extern.h>
94
95 caddr_t zeropage;
96 boolean_t __mm_mem_addr(paddr_t);
97
98 #define mmread mmrw
99 #define mmwrite mmrw
100 cdev_decl(mm);
101
102
103 int
mmopen(dev_t dev,int flag,int mode,struct proc * p)104 mmopen(dev_t dev, int flag, int mode, struct proc *p)
105 {
106 extern int allowkmem;
107
108 switch (minor(dev)) {
109 case 0:
110 case 1:
111 if ((int)atomic_load_int(&securelevel) <= 0 ||
112 atomic_load_int(&allowkmem))
113 break;
114 return (EPERM);
115 case 2:
116 case 12:
117 break;
118 default:
119 return (ENXIO);
120 }
121 return (0);
122 }
123
124 int
mmclose(dev_t dev,int flag,int mode,struct proc * p)125 mmclose(dev_t dev, int flag, int mode, struct proc *p)
126 {
127 return (0);
128 }
129
130 int
mmrw(dev_t dev,struct uio * uio,int flags)131 mmrw(dev_t dev, struct uio *uio, int flags)
132 {
133 struct iovec *iov;
134 vaddr_t v, o;
135 size_t c;
136 int error = 0;
137
138 while (uio->uio_resid > 0 && !error) {
139 iov = uio->uio_iov;
140 if (iov->iov_len == 0) {
141 uio->uio_iov++;
142 uio->uio_iovcnt--;
143 if (uio->uio_iovcnt < 0)
144 panic("mmrw");
145 continue;
146 }
147
148 v = uio->uio_offset;
149
150 switch (minor(dev)) {
151 case 0:
152 /* Physical address */
153 if (__mm_mem_addr(v)) {
154 o = v & PGOFSET;
155 c = ulmin(uio->uio_resid, PAGE_SIZE - o);
156 error = uiomove((caddr_t)SH3_PHYS_TO_P1SEG(v),
157 c, uio);
158 } else {
159 return (EFAULT);
160 }
161 break;
162
163 case 1:
164 if (v < SH3_P1SEG_BASE) /* P0 */
165 return (EFAULT);
166 if (v < SH3_P2SEG_BASE) { /* P1 */
167 /* permitted */
168 /*
169 if (__mm_mem_addr(SH3_P1SEG_TO_PHYS(v))
170 == FALSE)
171 return (EFAULT);
172 */
173 c = ulmin(iov->iov_len, MAXPHYS);
174 error = uiomove((caddr_t)v, c, uio);
175 } else if (v < SH3_P3SEG_BASE) /* P2 */
176 return (EFAULT);
177 else { /* P3 */
178 c = ulmin(iov->iov_len, MAXPHYS);
179 if (!uvm_kernacc((void *)v, c,
180 uio->uio_rw == UIO_READ ? B_READ : B_WRITE))
181 return (EFAULT);
182 error = uiomove((caddr_t)v, c, uio);
183 }
184 break;
185
186 case 2:
187 if (uio->uio_rw == UIO_WRITE)
188 uio->uio_resid = 0;
189 return (0);
190
191 case 12:
192 if (uio->uio_rw == UIO_WRITE) {
193 uio->uio_resid = 0;
194 return (0);
195 }
196 if (zeropage == NULL)
197 zeropage = malloc(PAGE_SIZE, M_TEMP,
198 M_WAITOK | M_ZERO);
199 c = ulmin(iov->iov_len, PAGE_SIZE);
200 error = uiomove(zeropage, c, uio);
201 break;
202
203 default:
204 return (ENXIO);
205 }
206 }
207
208 return (error);
209 }
210
211 paddr_t
mmmmap(dev_t dev,off_t off,int prot)212 mmmmap(dev_t dev, off_t off, int prot)
213 {
214 struct proc *p = curproc;
215
216 if (minor(dev) != 0)
217 return (-1);
218
219 if (__mm_mem_addr((paddr_t)off) == FALSE && suser(p) != 0)
220 return (-1);
221 return ((paddr_t)off);
222 }
223
224 int
mmioctl(dev_t dev,u_long cmd,caddr_t data,int flags,struct proc * p)225 mmioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
226 {
227 switch (cmd) {
228 case FIOASYNC:
229 /* handled by fd layer */
230 return 0;
231 }
232
233 return (ENOTTY);
234 }
235
236 /*
237 * boolean_t __mm_mem_addr(paddr_t pa):
238 * Check specified physical address is in physical memory, with the
239 * kernel image off-limits.
240 */
241 boolean_t
__mm_mem_addr(paddr_t pa)242 __mm_mem_addr(paddr_t pa)
243 {
244 #if 0
245 extern vaddr_t kernend; /* from machdep.c */
246 #endif
247 struct vm_physseg *seg;
248 unsigned int segno;
249
250 for (segno = 0, seg = vm_physmem; segno < vm_nphysseg; segno++, seg++) {
251 if (pa < seg->start || pa >= seg->end)
252 continue;
253
254 #if 0
255 /*
256 * This assumes the kernel image occupies the beginning of a
257 * memory segment.
258 */
259 if (kernend >= seg->start && kernend < seg->end) {
260 if (pa < kernend)
261 return (FALSE);
262 }
263 #endif
264
265 return (TRUE);
266 }
267
268 return (FALSE);
269 }
270