1 /* 2 * Copyright (c) 1982, 1986 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * @(#)mem.c 7.1 (Berkeley) 06/05/86 7 */ 8 9 /* 10 * Memory special file 11 */ 12 13 #include "pte.h" 14 15 #include "param.h" 16 #include "dir.h" 17 #include "user.h" 18 #include "conf.h" 19 #include "buf.h" 20 #include "systm.h" 21 #include "vm.h" 22 #include "cmap.h" 23 #include "uio.h" 24 25 #include "mtpr.h" 26 27 mmread(dev, uio) 28 dev_t dev; 29 struct uio *uio; 30 { 31 32 return (mmrw(dev, uio, UIO_READ)); 33 } 34 35 mmwrite(dev, uio) 36 dev_t dev; 37 struct uio *uio; 38 { 39 40 return (mmrw(dev, uio, UIO_WRITE)); 41 } 42 43 mmrw(dev, uio, rw) 44 dev_t dev; 45 struct uio *uio; 46 enum uio_rw rw; 47 { 48 register int o; 49 register u_int c, v; 50 register struct iovec *iov; 51 int error = 0; 52 extern int umbabeg, umbaend; 53 54 55 while (uio->uio_resid > 0 && error == 0) { 56 iov = uio->uio_iov; 57 if (iov->iov_len == 0) { 58 uio->uio_iov++; 59 uio->uio_iovcnt--; 60 if (uio->uio_iovcnt < 0) 61 panic("mmrw"); 62 continue; 63 } 64 switch (minor(dev)) { 65 66 /* minor device 0 is physical memory */ 67 case 0: 68 v = btop(uio->uio_offset); 69 if (v >= physmem) 70 goto fault; 71 *(int *)mmap = v | PG_V | 72 (rw == UIO_READ ? PG_KR : PG_KW); 73 mtpr(TBIS, vmmap); 74 o = (int)uio->uio_offset & PGOFSET; 75 c = (u_int)(NBPG - ((int)iov->iov_base & PGOFSET)); 76 c = MIN(c, (u_int)(NBPG - o)); 77 c = MIN(c, (u_int)iov->iov_len); 78 error = uiomove((caddr_t)&vmmap[o], (int)c, rw, uio); 79 continue; 80 81 /* minor device 1 is kernel memory */ 82 case 1: 83 if ((caddr_t)uio->uio_offset < (caddr_t)&umbabeg && 84 (caddr_t)uio->uio_offset + uio->uio_resid >= (caddr_t)&umbabeg) 85 goto fault; 86 if ((caddr_t)uio->uio_offset >= (caddr_t)&umbabeg && 87 (caddr_t)uio->uio_offset < (caddr_t)&umbaend) 88 goto fault; 89 c = iov->iov_len; 90 if (!kernacc((caddr_t)uio->uio_offset, c, rw == UIO_READ ? B_READ : B_WRITE)) 91 goto fault; 92 error = uiomove((caddr_t)uio->uio_offset, (int)c, rw, uio); 93 continue; 94 95 /* minor device 2 is EOF/RATHOLE */ 96 case 2: 97 if (rw == UIO_READ) 98 return (0); 99 c = iov->iov_len; 100 break; 101 102 /* minor device 3 is unibus memory (addressed by shorts) */ 103 case 3: 104 c = iov->iov_len; 105 if (!kernacc((caddr_t)uio->uio_offset, c, rw == UIO_READ ? B_READ : B_WRITE)) 106 goto fault; 107 if (!useracc(iov->iov_base, c, rw == UIO_READ ? B_WRITE : B_READ)) 108 goto fault; 109 error = UNIcpy((caddr_t)uio->uio_offset, iov->iov_base, 110 (int)c, rw); 111 break; 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 return (error); 121 fault: 122 return (EFAULT); 123 } 124 125 /* 126 * UNIBUS Address Space <--> User Space transfer 127 */ 128 UNIcpy(uniadd, usradd, n, rw) 129 caddr_t uniadd, usradd; 130 register int n; 131 enum uio_rw rw; 132 { 133 register short *from, *to; 134 135 if (rw == UIO_READ) { 136 from = (short *)uniadd; 137 to = (short *)usradd; 138 } else { 139 from = (short *)usradd; 140 to = (short *)uniadd; 141 } 142 for (n >>= 1; n > 0; n--) 143 *to++ = *from++; 144 return (0); 145 } 146