1 /* 2 * Copyright (c) 1988 University of Utah. 3 * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * the Systems Programming Group of the University of Utah Computer 8 * Science Department. 9 * 10 * %sccs.include.redist.c% 11 * 12 * from: Utah $Hdr: mem.c 1.14 90/10/12$ 13 * 14 * @(#)mem.c 7.6 (Berkeley) 08/28/91 15 */ 16 17 /* 18 * Memory special file 19 */ 20 21 #include "param.h" 22 #include "conf.h" 23 #include "buf.h" 24 #include "systm.h" 25 #include "malloc.h" 26 27 #include "../include/cpu.h" 28 29 #include "vm/vm_param.h" 30 #include "vm/lock.h" 31 #include "vm/pmap.h" 32 #include "vm/vm_prot.h" 33 34 /*ARGSUSED*/ 35 mmrw(dev, uio, flags) 36 dev_t dev; 37 struct uio *uio; 38 int flags; 39 { 40 register int o; 41 register u_int c, v; 42 register struct iovec *iov; 43 int error = 0; 44 caddr_t zbuf = NULL; 45 extern u_int lowram; 46 47 while (uio->uio_resid > 0 && error == 0) { 48 iov = uio->uio_iov; 49 if (iov->iov_len == 0) { 50 uio->uio_iov++; 51 uio->uio_iovcnt--; 52 if (uio->uio_iovcnt < 0) 53 panic("mmrw"); 54 continue; 55 } 56 switch (minor(dev)) { 57 58 /* minor device 0 is physical memory */ 59 case 0: 60 v = uio->uio_offset; 61 #ifndef DEBUG 62 /* allow reads only in RAM (except for DEBUG) */ 63 if (v >= 0xFFFFFFFC || v < lowram) 64 return (EFAULT); 65 #endif 66 pmap_enter(pmap_kernel(), vmmap, trunc_page(v), 67 uio->uio_rw == UIO_READ ? 68 VM_PROT_READ : VM_PROT_WRITE, TRUE); 69 o = (int)uio->uio_offset & PGOFSET; 70 c = (u_int)(NBPG - ((int)iov->iov_base & PGOFSET)); 71 c = MIN(c, (u_int)(NBPG - o)); 72 c = MIN(c, (u_int)iov->iov_len); 73 error = uiomove((caddr_t)&vmmap[o], (int)c, uio); 74 pmap_remove(pmap_kernel(), vmmap, &vmmap[NBPG]); 75 continue; 76 77 /* minor device 1 is kernel memory */ 78 case 1: 79 c = MIN(iov->iov_len, MAXPHYS); 80 if (!kernacc((caddr_t)uio->uio_offset, c, 81 uio->uio_rw == UIO_READ ? B_READ : B_WRITE)) 82 return (EFAULT); 83 error = uiomove((caddr_t)uio->uio_offset, (int)c, uio); 84 continue; 85 86 /* minor device 2 is EOF/RATHOLE */ 87 case 2: 88 if (uio->uio_rw == UIO_WRITE) 89 uio->uio_resid = 0; 90 return (0); 91 92 /* minor device 12 (/dev/zero) is source of nulls on read, rathole on write */ 93 case 12: 94 if (uio->uio_rw == UIO_WRITE) { 95 c = iov->iov_len; 96 break; 97 } 98 if (zbuf == NULL) { 99 zbuf = (caddr_t) 100 malloc(CLBYTES, M_TEMP, M_WAITOK); 101 bzero(zbuf, CLBYTES); 102 } 103 c = MIN(iov->iov_len, CLBYTES); 104 error = uiomove(zbuf, (int)c, uio); 105 continue; 106 107 default: 108 return (ENXIO); 109 } 110 if (error) 111 break; 112 iov->iov_base += c; 113 iov->iov_len -= c; 114 uio->uio_offset += c; 115 uio->uio_resid -= c; 116 } 117 if (zbuf) 118 free(zbuf, M_TEMP); 119 return (error); 120 } 121