1: /* 2: * Copyright (c) 1982, 1986 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: * @(#)vm_machdep.c 7.1 (Berkeley) 6/5/86 7: */ 8: 9: #include "pte.h" 10: 11: #include "param.h" 12: #include "systm.h" 13: #include "dir.h" 14: #include "user.h" 15: #include "proc.h" 16: #include "cmap.h" 17: #include "mount.h" 18: #include "vm.h" 19: #include "text.h" 20: 21: #include "mtpr.h" 22: 23: /* 24: * Set a red zone in the kernel stack after the u. area. 25: */ 26: setredzone(pte, vaddr) 27: register struct pte *pte; 28: caddr_t vaddr; 29: { 30: 31: pte += (sizeof (struct user) + NBPG - 1) / NBPG; 32: *(int *)pte &= ~PG_PROT; 33: *(int *)pte |= PG_URKR; 34: if (vaddr) 35: mtpr(TBIS, vaddr + sizeof (struct user)); 36: } 37: 38: #ifndef mapin 39: mapin(pte, v, pfnum, count, prot) 40: struct pte *pte; 41: u_int v, pfnum; 42: int count, prot; 43: { 44: 45: while (count > 0) { 46: *(int *)pte++ = pfnum | prot; 47: mtpr(TBIS, ptob(v)); 48: v++; 49: pfnum++; 50: count--; 51: } 52: } 53: #endif 54: 55: #ifdef notdef 56: /*ARGSUSED*/ 57: mapout(pte, size) 58: register struct pte *pte; 59: int size; 60: { 61: 62: panic("mapout"); 63: } 64: #endif 65: 66: /* 67: * Check for valid program size 68: * NB - Check data and data growth separately as they may overflow 69: * when summed together. 70: */ 71: chksize(ts, ids, uds, ss) 72: unsigned ts, ids, uds, ss; 73: { 74: extern unsigned maxtsize; 75: 76: if (ctob(ts) > maxtsize || 77: ctob(ids) > u.u_rlimit[RLIMIT_DATA].rlim_cur || 78: ctob(uds) > u.u_rlimit[RLIMIT_DATA].rlim_cur || 79: ctob(ids + uds) > u.u_rlimit[RLIMIT_DATA].rlim_cur || 80: ctob(ss) > u.u_rlimit[RLIMIT_STACK].rlim_cur) { 81: u.u_error = ENOMEM; 82: return (1); 83: } 84: return (0); 85: } 86: 87: /*ARGSUSED*/ 88: newptes(pte, v, size) 89: register struct pte *pte; 90: u_int v; 91: register int size; 92: { 93: register caddr_t a = ptob(v); 94: 95: #ifdef lint 96: pte = pte; 97: #endif 98: if (size >= 8) { 99: mtpr(TBIA, 0); 100: return; 101: } 102: while (size > 0) { 103: mtpr(TBIS, a); 104: a += NBPG; 105: size--; 106: } 107: } 108: 109: /* 110: * Change protection codes of text segment. 111: * Have to flush translation buffer since this 112: * affect virtual memory mapping of current process. 113: */ 114: chgprot(addr, tprot) 115: caddr_t addr; 116: long tprot; 117: { 118: unsigned v; 119: int tp; 120: register struct pte *pte; 121: register struct cmap *c; 122: 123: v = clbase(btop(addr)); 124: if (!isatsv(u.u_procp, v)) { 125: u.u_error = EFAULT; 126: return (0); 127: } 128: tp = vtotp(u.u_procp, v); 129: pte = tptopte(u.u_procp, tp); 130: if (pte->pg_fod == 0 && pte->pg_pfnum) { 131: c = &cmap[pgtocm(pte->pg_pfnum)]; 132: if (c->c_blkno && c->c_mdev != MSWAPX) 133: munhash(mount[c->c_mdev].m_dev, 134: (daddr_t)(u_long)c->c_blkno); 135: } 136: *(int *)pte &= ~PG_PROT; 137: *(int *)pte |= tprot; 138: distcl(pte); 139: tbiscl(v); 140: return (1); 141: } 142: 143: settprot(tprot) 144: long tprot; 145: { 146: register int *ptaddr, i; 147: 148: ptaddr = (int *)mfpr(P0BR); 149: for (i = 0; i < u.u_tsize; i++) { 150: ptaddr[i] &= ~PG_PROT; 151: ptaddr[i] |= tprot; 152: } 153: mtpr(TBIA, 0); 154: } 155: 156: /* 157: * Rest are machine-dependent 158: */ 159: 160: getmemc(addr) 161: caddr_t addr; 162: { 163: register int c; 164: struct pte savemap; 165: 166: savemap = mmap[0]; 167: *(int *)mmap = PG_V | PG_KR | btop(addr); 168: mtpr(TBIS, vmmap); 169: c = *(char *)&vmmap[(int)addr & PGOFSET]; 170: mmap[0] = savemap; 171: mtpr(TBIS, vmmap); 172: return (c & 0377); 173: } 174: 175: putmemc(addr, val) 176: caddr_t addr; 177: { 178: struct pte savemap; 179: 180: savemap = mmap[0]; 181: *(int *)mmap = PG_V | PG_KW | btop(addr); 182: mtpr(TBIS, vmmap); 183: *(char *)&vmmap[(int)addr & PGOFSET] = val; 184: mmap[0] = savemap; 185: mtpr(TBIS, vmmap); 186: } 187: 188: /* 189: * Move pages from one kernel virtual address to another. 190: * Both addresses are assumed to reside in the Sysmap, 191: * and size must be a multiple of CLSIZE. 192: */ 193: pagemove(from, to, size) 194: register caddr_t from, to; 195: int size; 196: { 197: register struct pte *fpte, *tpte; 198: 199: if (size % CLBYTES) 200: panic("pagemove"); 201: fpte = &Sysmap[btop(from - 0x80000000)]; 202: tpte = &Sysmap[btop(to - 0x80000000)]; 203: while (size > 0) { 204: *tpte++ = *fpte; 205: *(int *)fpte++ = 0; 206: mtpr(TBIS, from); 207: mtpr(TBIS, to); 208: from += NBPG; 209: to += NBPG; 210: size -= NBPG; 211: } 212: }