1 /* mem.c 1.4 86/12/15 */ 2 3 /* 4 * Memory special file 5 */ 6 7 #include "../machine/pte.h" 8 9 #include "../h/param.h" 10 #include "../h/dir.h" 11 #include "../h/user.h" 12 #include "../h/conf.h" 13 #include "../h/buf.h" 14 #include "../h/systm.h" 15 #include "../h/vm.h" 16 #include "../h/cmap.h" 17 #include "../h/uio.h" 18 19 #include "../tahoe/mtpr.h" 20 21 mmread(dev, uio) 22 dev_t dev; 23 struct uio *uio; 24 { 25 26 return (mmrw(dev, uio, UIO_READ)); 27 } 28 29 mmwrite(dev, uio) 30 dev_t dev; 31 struct uio *uio; 32 { 33 34 return (mmrw(dev, uio, UIO_WRITE)); 35 } 36 37 mmrw(dev, uio, rw) 38 dev_t dev; 39 struct uio *uio; 40 enum uio_rw rw; 41 { 42 register int o; 43 register u_int c, v; 44 register struct iovec *iov; 45 int error = 0; 46 extern caddr_t vmembeg, vmemend; 47 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 = btop(uio->uio_offset); 63 if (v >= physmem) 64 goto fault; 65 *(int *)mmap = v | PG_V | 66 (rw == UIO_READ ? PG_KR : PG_KW); 67 mtpr(TBIS, vmmap); 68 o = (int)uio->uio_offset & PGOFSET; 69 c = (u_int)(NBPG - ((int)iov->iov_base & PGOFSET)); 70 c = MIN(c, (u_int)(NBPG - o)); 71 c = MIN(c, (u_int)iov->iov_len); 72 error = uiomove((caddr_t)&vmmap[o], (int)c, rw, uio); 73 continue; 74 75 /* minor device 1 is kernel memory */ 76 case 1: 77 if ((caddr_t)uio->uio_offset < (caddr_t)&vmembeg && 78 (caddr_t)uio->uio_offset + uio->uio_resid >= (caddr_t)&vmembeg) 79 goto fault; 80 if ((caddr_t)uio->uio_offset >= (caddr_t)&vmembeg && 81 (caddr_t)uio->uio_offset < (caddr_t)&vmemend) 82 goto fault; 83 c = iov->iov_len; 84 if (!kernacc((caddr_t)uio->uio_offset, c, rw == UIO_READ ? B_READ : B_WRITE)) 85 goto fault; 86 error = uiomove((caddr_t)uio->uio_offset, (int)c, rw, uio); 87 continue; 88 89 /* minor device 2 is EOF/RATHOLE */ 90 case 2: 91 if (rw == UIO_READ) 92 return (0); 93 c = iov->iov_len; 94 break; 95 96 /* minor device 3 is versabus memory (addressed by shorts) */ 97 case 3: 98 c = iov->iov_len; 99 if (!kernacc((caddr_t)uio->uio_offset, c, rw == UIO_READ ? B_READ : B_WRITE)) 100 goto fault; 101 if (!useracc(iov->iov_base, c, rw == UIO_READ ? B_WRITE : B_READ)) 102 goto fault; 103 error = VERSAcpy((caddr_t)uio->uio_offset, iov->iov_base, 104 (int)c, rw); 105 break; 106 } 107 if (error) 108 break; 109 iov->iov_base += c; 110 iov->iov_len -= c; 111 uio->uio_offset += c; 112 uio->uio_resid -= c; 113 } 114 return (error); 115 fault: 116 return (EFAULT); 117 } 118 119 /* 120 * VERSABUS Address Space <--> User Space transfer 121 */ 122 VERSAcpy(versaadd, usradd, n, rw) 123 caddr_t versaadd, usradd; 124 register int n; 125 enum uio_rw rw; 126 { 127 register short *from, *to; 128 129 if(((int)versaadd&1) || ((int)usradd&1)) 130 return (EFAULT); 131 if (rw == UIO_READ) { 132 from = (short *)versaadd; 133 to = (short *)usradd; 134 } else { 135 from = (short *)usradd; 136 to = (short *)versaadd; 137 } 138 for (n >>= 1; n > 0; n--) 139 *to++ = *from++; 140 return (0); 141 } 142