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