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 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 125 mmclose(dev_t dev, int flag, int mode, struct proc *p) 126 { 127 return (0); 128 } 129 130 int 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 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 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 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