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