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, and code derived from software contributed to 9 * Berkeley by William Jolitz. 10 * 11 * %sccs.include.redist.c% 12 * 13 * from: Utah $Hdr: mem.c 1.13 89/10/08$ 14 * @(#)mem.c 5.6 (Berkeley) 01/19/91 15 */ 16 17 /* 18 * Memory special file 19 */ 20 21 #include "machine/pte.h" 22 23 #include "param.h" 24 #include "user.h" 25 #include "conf.h" 26 #include "buf.h" 27 #include "systm.h" 28 #include "vm.h" 29 #include "cmap.h" 30 #include "uio.h" 31 #include "malloc.h" 32 33 #include "machine/cpu.h" 34 35 /*ARGSUSED*/ 36 mmrw(dev, uio, flags) 37 dev_t dev; 38 struct uio *uio; 39 int flags; 40 { 41 register int o; 42 register u_int c, v; 43 register struct iovec *iov; 44 int error = 0; 45 caddr_t zbuf = NULL; 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 *(int *)mmap = (v & PG_FRAME) | PG_V | 62 (uio->uio_rw == UIO_READ ? PG_KR : PG_KW); 63 load_cr3(u.u_pcb.pcb_cr3); 64 o = (int)uio->uio_offset & PGOFSET; 65 c = (u_int)(NBPG - ((int)iov->iov_base & PGOFSET)); 66 c = MIN(c, (u_int)(NBPG - o)); 67 c = MIN(c, (u_int)iov->iov_len); 68 error = uiomove((caddr_t)&vmmap[o], (int)c, uio); 69 continue; 70 71 /* minor device 1 is kernel memory */ 72 case 1: 73 c = iov->iov_len; 74 if (!kernacc((caddr_t)uio->uio_offset, c, 75 uio->uio_rw == UIO_READ ? B_READ : B_WRITE)) 76 goto fault; 77 error = uiomove((caddr_t)uio->uio_offset, (int)c, uio); 78 continue; 79 80 /* minor device 2 is EOF/RATHOLE */ 81 case 2: 82 if (uio->uio_rw == UIO_READ) 83 return (0); 84 c = iov->iov_len; 85 break; 86 87 /* minor device 12 (/dev/zero) is source of nulls on read, rathole on write */ 88 case 12: 89 if (uio->uio_rw == UIO_WRITE) { 90 c = iov->iov_len; 91 break; 92 } 93 if (zbuf == NULL) { 94 zbuf = (caddr_t) 95 malloc(CLBYTES, M_TEMP, M_WAITOK); 96 bzero(zbuf, CLBYTES); 97 } 98 c = MIN(iov->iov_len, CLBYTES); 99 error = uiomove(zbuf, (int)c, uio); 100 continue; 101 102 default: 103 return (ENXIO); 104 } 105 if (error) 106 break; 107 iov->iov_base += c; 108 iov->iov_len -= c; 109 uio->uio_offset += c; 110 uio->uio_resid -= c; 111 } 112 if (zbuf) 113 free(zbuf, M_TEMP); 114 return (error); 115 fault: 116 return (EFAULT); 117 } 118