1 /* mem.c 3.4 06/07/80 */ 2 3 /* 4 * Memory special file 5 * minor device 0 is physical memory 6 * minor device 1 is kernel memory 7 * minor device 2 is EOF/RATHOLE 8 * minor device 3 is unibus memory (addressed by shorts) 9 */ 10 11 #include "../h/param.h" 12 #include "../h/dir.h" 13 #include "../h/user.h" 14 #include "../h/conf.h" 15 #include "../h/buf.h" 16 #include "../h/systm.h" 17 #include "../h/pte.h" 18 #include "../h/mtpr.h" 19 #include "../h/vm.h" 20 #include "../h/cmap.h" 21 22 mmread(dev) 23 { 24 register int o; 25 register unsigned c, v; 26 27 switch (minor(dev)) { 28 29 case 0: 30 while (u.u_count != 0 && u.u_error == 0) { 31 if (fubyte(u.u_base) == -1) 32 goto fault; 33 v = btop(u.u_offset); 34 if (v >= physmem) 35 goto fault; 36 *(int *)mmap = v | (PG_V | PG_KR); 37 mtpr(TBIS, vmmap); 38 o = (int)u.u_offset & PGOFSET; 39 c = min((unsigned)(NBPG - o), u.u_count); 40 c = min(c, (unsigned)(NBPG - ((int)u.u_base&PGOFSET))); 41 if (copyout((caddr_t)&vmmap[o], u.u_base, c)) 42 goto fault; 43 u.u_count -= c; 44 u.u_base += c; 45 u.u_offset += c; 46 } 47 return; 48 49 case 1: 50 if (u.u_uid != 0) { 51 if ((caddr_t)u.u_offset < (caddr_t)&umbabeg && 52 (caddr_t)u.u_offset + u.u_count >= (caddr_t)&umbabeg) 53 goto fault; 54 if ((caddr_t)u.u_offset >= (caddr_t)&umbabeg && 55 (caddr_t)u.u_offset < (caddr_t)&umbaend) 56 goto fault; 57 } 58 if (!kernacc((caddr_t)u.u_offset, u.u_count, B_READ)) 59 goto fault; 60 if (copyout((caddr_t)u.u_offset, u.u_base, u.u_count)) 61 goto fault; 62 c = u.u_count; 63 u.u_count = 0; 64 u.u_base += c; 65 u.u_offset += c; 66 return; 67 68 case 2: 69 return; 70 71 case 3: 72 if (!kernacc((caddr_t)u.u_offset, u.u_count, B_READ)) 73 goto fault; 74 if (!useracc(u.u_base, u.u_count, B_WRITE)) 75 goto fault; 76 UNIcpy((caddr_t)u.u_offset, u.u_base, u.u_count, B_READ); 77 c = u.u_count; 78 u.u_count = 0; 79 u.u_base += c; 80 u.u_offset += c; 81 return; 82 } 83 fault: 84 u.u_error = EFAULT; 85 return; 86 } 87 88 mmwrite(dev) 89 { 90 register int o; 91 register unsigned c, v; 92 93 switch (minor(dev)) { 94 95 case 0: 96 while (u.u_count != 0 && u.u_error == 0) { 97 if (fubyte(u.u_base) == -1) 98 goto fault; 99 v = btop(u.u_offset); 100 if (v >= physmem) 101 goto fault; 102 *(int *)mmap = v | (PG_V | PG_KW); 103 mtpr(TBIS, vmmap); 104 o = (int)u.u_offset & PGOFSET; 105 c = min((unsigned)(NBPG - o), u.u_count); 106 c = min(c, (unsigned)(NBPG - ((int)u.u_base&PGOFSET))); 107 if (copyin(u.u_base, (caddr_t)&vmmap[o], c)) 108 goto fault; 109 u.u_count -= c; 110 u.u_base += c; 111 u.u_offset += c; 112 } 113 return; 114 115 case 1: 116 if (!kernacc((caddr_t)u.u_offset, u.u_count, B_WRITE)) 117 goto fault; 118 if (copyin(u.u_base, (caddr_t)u.u_offset, u.u_count)) 119 goto fault; 120 u.u_base += u.u_count; 121 u.u_offset += u.u_count; 122 u.u_count = 0; 123 return; 124 125 case 2: 126 u.u_offset += u.u_count; 127 u.u_count = 0; 128 return; 129 130 case 3: 131 if (!kernacc((caddr_t)u.u_offset, u.u_count, B_WRITE)) 132 goto fault; 133 if (!useracc(u.u_base, u.u_count, B_READ)) 134 goto fault; 135 UNIcpy((caddr_t)u.u_offset, u.u_base, u.u_count, B_WRITE); 136 u.u_base += u.u_count; 137 u.u_offset += u.u_count; 138 u.u_count = 0; 139 return; 140 } 141 fault: 142 u.u_error = EFAULT; 143 return; 144 } 145 146 /* 147 * UNIBUS Address Space <--> User Space transfer 148 */ 149 UNIcpy(uniadd, usradd, bknt, direct) 150 caddr_t uniadd, usradd; 151 unsigned bknt; 152 { 153 register short *from, *to; 154 register int i; 155 156 if (direct == B_READ) { 157 from = (short *) uniadd; 158 to = (short *) usradd; 159 } else { 160 from = (short *) usradd; 161 to = (short *) uniadd; 162 } 163 for (i = (bknt>>1); i > 0; i--) 164 *to++ = *from++; 165 } 166