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