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