1 /*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * William Jolitz. 7 * 8 * %sccs.include.noredist.c% 9 * 10 * @(#)mem.c 5.5 (Berkeley) 11/25/90 11 */ 12 13 /* 14 * Memory special file 15 */ 16 17 #include "machine/pte.h" 18 19 #include "param.h" 20 #include "dir.h" 21 #include "user.h" 22 #include "conf.h" 23 #include "buf.h" 24 #include "systm.h" 25 #include "vm.h" 26 #include "cmap.h" 27 #include "uio.h" 28 29 mmread(dev, uio) 30 dev_t dev; 31 struct uio *uio; 32 { 33 34 return (mmrw(dev, uio, UIO_READ)); 35 } 36 37 mmwrite(dev, uio) 38 dev_t dev; 39 struct uio *uio; 40 { 41 42 return (mmrw(dev, uio, UIO_WRITE)); 43 } 44 45 mmrw(dev, uio, rw) 46 dev_t dev; 47 struct uio *uio; 48 enum uio_rw rw; 49 { 50 register int o; 51 register u_int c, v; 52 register struct iovec *iov; 53 int error = 0; 54 55 56 while (uio->uio_resid > 0 && error == 0) { 57 iov = uio->uio_iov; 58 if (iov->iov_len == 0) { 59 uio->uio_iov++; 60 uio->uio_iovcnt--; 61 if (uio->uio_iovcnt < 0) 62 panic("mmrw"); 63 continue; 64 } 65 switch (minor(dev)) { 66 67 /* minor device 0 is physical memory */ 68 case 0: 69 v = btop(uio->uio_offset); 70 if (v >= physmem) 71 goto fault; 72 *(int *)mmap = ctob(v) | PG_V | 73 (rw == UIO_READ ? PG_KR : PG_KW); 74 load_cr3(u.u_pcb.pcb_ptd); 75 o = (int)uio->uio_offset & PGOFSET; 76 c = (u_int)(NBPG - ((int)iov->iov_base & PGOFSET)); 77 c = MIN(c, (u_int)(NBPG - o)); 78 c = MIN(c, (u_int)iov->iov_len); 79 error = uiomove((caddr_t)&vmmap[o], (int)c, rw, uio); 80 continue; 81 82 /* minor device 1 is kernel memory */ 83 case 1: 84 c = iov->iov_len; 85 if (!kernacc((caddr_t)uio->uio_offset, c, rw == UIO_READ ? B_READ : B_WRITE)) 86 goto fault; 87 error = uiomove((caddr_t)uio->uio_offset, (int)c, rw, uio); 88 continue; 89 90 /* minor device 2 is EOF/RATHOLE */ 91 case 2: 92 if (rw == UIO_READ) 93 return (0); 94 c = iov->iov_len; 95 break; 96 97 } 98 if (error) 99 break; 100 iov->iov_base += c; 101 iov->iov_len -= c; 102 uio->uio_offset += c; 103 uio->uio_resid -= c; 104 } 105 return (error); 106 fault: 107 return (EFAULT); 108 } 109