1 /* vm_machdep.c 1.1 85/07/21 */ 2 3 #include "../machine/pte.h" 4 5 #include "../h/param.h" 6 #include "../h/systm.h" 7 #include "../h/dir.h" 8 #include "../h/user.h" 9 #include "../h/proc.h" 10 #include "../h/cmap.h" 11 #include "../h/mount.h" 12 #include "../h/vm.h" 13 #include "../h/text.h" 14 15 #include "../machine/mtpr.h" 16 17 /* 18 * Set a red zone in the kernel stack after the u. area. 19 */ 20 setredzone(pte, vaddr) 21 register struct pte *pte; 22 caddr_t vaddr; 23 { 24 25 pte += (sizeof (struct user) + NBPG - 1) / NBPG; 26 *(int *)pte &= ~PG_PROT; 27 *(int *)pte |= PG_URKR; 28 if (vaddr) 29 mtpr(vaddr + sizeof (struct user) + NBPG - 1, TBIS); 30 } 31 32 #ifndef mapin 33 mapin(pte, v, pfnum, count, prot) 34 struct pte *pte; 35 u_int v, pfnum; 36 int count, prot; 37 { 38 39 while (count > 0) { 40 *(int *)pte++ = pfnum | prot; 41 mtpr(ptob(v), TBIS); 42 v++; 43 pfnum++; 44 count--; 45 } 46 } 47 #endif 48 49 #ifdef notdef 50 /*ARGSUSED*/ 51 mapout(pte, size) 52 register struct pte *pte; 53 int size; 54 { 55 56 panic("mapout"); 57 } 58 #endif 59 60 /* 61 * Check for valid program size 62 */ 63 chksize(ts, ds, ss) 64 register unsigned ts, ds, ss; 65 { 66 static int maxdmap = 0; 67 68 if (ts > MAXTSIZ || ds > MAXDSIZ || ss > MAXSSIZ) { 69 u.u_error = ENOMEM; 70 return (1); 71 } 72 /* check for swap map overflow */ 73 if (maxdmap == 0) { 74 register int i, blk; 75 76 blk = dmmin; 77 for (i = 0; i < NDMAP; i++) { 78 maxdmap += blk; 79 if (blk < dmmax) 80 blk *= 2; 81 } 82 } 83 if (ctod(ts) > NXDAD * dmtext || 84 ctod(ds) > maxdmap || ctod(ss) > maxdmap) { 85 u.u_error = ENOMEM; 86 return (1); 87 } 88 /* 89 * Make sure the process isn't bigger than our 90 * virtual memory limit. 91 * 92 * THERE SHOULD BE A CONSTANT FOR THIS. 93 */ 94 if (ts + ds + ss + LOWPAGES + HIGHPAGES > btoc(USRSTACK)) { 95 u.u_error = ENOMEM; 96 return (1); 97 } 98 return (0); 99 } 100 101 /*ARGSUSED*/ 102 newptes(pte, v, size) 103 register struct pte *pte; 104 u_int v; 105 register int size; 106 { 107 register caddr_t a = ptob(v); 108 109 #ifdef lint 110 pte = pte; 111 #endif 112 if (size >= 8) { 113 mtpr(0, TBIA); 114 return; 115 } 116 while (size > 0) { 117 mtpr(a, TBIS); 118 a += NBPG; 119 size--; 120 } 121 } 122 123 /* 124 * Change protection codes of text segment. 125 * Have to flush translation buffer since this 126 * affect virtual memory mapping of current process. 127 */ 128 chgprot(addr, tprot) 129 caddr_t addr; 130 long tprot; 131 { 132 unsigned v; 133 int tp; 134 register struct pte *pte; 135 register struct cmap *c; 136 137 v = clbase(btop(addr)); 138 if (!isatsv(u.u_procp, v)) { 139 u.u_error = EFAULT; 140 return (0); 141 } 142 tp = vtotp(u.u_procp, v); 143 pte = tptopte(u.u_procp, tp); 144 if (pte->pg_fod == 0 && pte->pg_pfnum) { 145 c = &cmap[pgtocm(pte->pg_pfnum)]; 146 if (c->c_blkno && c->c_mdev != MSWAPX) 147 munhash(mount[c->c_mdev].m_dev, 148 (daddr_t)(u_long)c->c_blkno); 149 } 150 *(int *)pte &= ~PG_PROT; 151 *(int *)pte |= tprot; 152 distcl(pte); 153 tbiscl(v); 154 return (1); 155 } 156 157 settprot(tprot) 158 long tprot; 159 { 160 register int *ptaddr, i; 161 162 ptaddr = (int *)mfpr(P0BR); 163 for (i = 0; i < u.u_tsize; i++) { 164 ptaddr[i] &= ~PG_PROT; 165 ptaddr[i] |= tprot; 166 } 167 mtpr(0, TBIA); 168 } 169 170 /* 171 * Rest are machine-dependent 172 */ 173 174 getmemc(addr) 175 caddr_t addr; 176 { 177 register int c; 178 struct pte savemap; 179 180 savemap = mmap[0]; 181 *(int *)mmap = PG_V | PG_KR | btop(addr); 182 mtpr(vmmap, TBIS); 183 uncache (&vmmap[(int)addr & PGOFSET]); 184 c = *(char *)&vmmap[(int)addr & PGOFSET]; 185 mmap[0] = savemap; 186 mtpr(vmmap, TBIS); 187 return (c & 0377); 188 } 189 190 putmemc(addr, val) 191 caddr_t addr; 192 { 193 struct pte savemap; 194 195 savemap = mmap[0]; 196 *(int *)mmap = PG_V | PG_KW | btop(addr); 197 mtpr(vmmap, TBIS); 198 *(char *)&vmmap[(int)addr & PGOFSET] = val; 199 200 mtpr (0, PADC); 201 mtpr (0, PACC); 202 203 mmap[0] = savemap; 204 mtpr(vmmap, TBIS); 205 } 206 207 /* 208 * Move pages from one kernel virtual address to another. 209 * Both addresses are assumed to reside in the Sysmap, 210 * and size must be a multiple of CLSIZE. 211 */ 212 pagemove(from, to, size) 213 register caddr_t from, to; 214 int size; 215 { 216 register struct pte *fpte, *tpte; 217 218 if (size % CLBYTES) 219 panic("pagemove"); 220 fpte = &Sysmap[btop(from - 0xC0000000)]; 221 tpte = &Sysmap[btop(to - 0xC0000000)]; 222 while (size > 0) { 223 *tpte++ = *fpte; 224 *(int *)fpte++ = 0; 225 mtpr(from, TBIS); 226 mtpr(to, TBIS); 227 mtpr(to, P1DC); /* purge !! */ 228 from += NBPG; 229 to += NBPG; 230 size -= NBPG; 231 } 232 } 233 234 #ifndef GLOBKEY 235 ckeyrelease(key) 236 /* 237 * release code key 238 */ 239 { 240 register int ipl,i,j ; 241 ipl = spl8(); 242 if (--ckey_cnt[key-1] < 0 ) { 243 /* 244 panic ("Code key release"); 245 */ 246 printf("Ckey release, key=%d\n", key); 247 ckey_cnt[key-1] = 0; 248 splx(ipl); 249 } 250 splx(ipl); 251 } 252 253 254 dkeyrelease(key) 255 /* 256 * release data key 257 */ 258 { 259 if (--dkey_cnt[key-1] != 0 ) panic ("Data key release"); 260 } 261 262 263 int 264 getcodekey() 265 /* 266 * Get a code key 267 */ 268 { 269 register int i, ipl, first; 270 271 first = 1; 272 ipl = spl8(); 273 retry: 274 for (i=0; i<255; i++) { 275 if ( (int)ckey_cache[i] == 0) { 276 ckey_cache[i] = 1; 277 ckey_cnt[i] = 1; 278 splx(ipl); 279 return (i+1); 280 }; 281 } 282 if ( !first) { 283 splx(ipl); 284 panic ("Not enough code keys\n"); 285 } 286 mtpr (0, PACC); 287 first = 0; 288 for (i=0; i<255; i++) 289 if ( ckey_cnt[i] > 0 ) ckey_cache[i] = 1; 290 else ckey_cache[i] = 0; 291 goto retry; 292 } 293 294 int 295 getdatakey() 296 /* 297 * Get a data key 298 */ 299 { 300 register int i, ipl, first; 301 302 first = 1; 303 ipl = spl8(); 304 retry: 305 for (i=0; i<255; i++) 306 if ( (int)dkey_cache[i] == 0) { 307 dkey_cache[i] = 1; 308 dkey_cnt[i] = 1; 309 splx(ipl); 310 return (i+1); 311 }; 312 if ( !first) { 313 splx(ipl); 314 panic("Not enough data keys\n"); 315 } 316 mtpr (0, PADC); 317 first = 0; 318 for (i=0; i<255; i++) 319 if ( dkey_cnt[i] > 0 ) dkey_cache[i] = 1; 320 else dkey_cache[i] = 0; 321 goto retry; 322 } 323 #endif 324 325 /* General (includes system) virtual address to physical */ 326 vtoph(p, v) 327 register struct proc *p; 328 register unsigned v; 329 { 330 register struct pte *thispte; 331 332 thispte = vtopte (p, btop(v)); 333 return ( (thispte->pg_pfnum << PGSHIFT) + (v & PGOFSET)); 334 } 335 336