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