1 /* vm_machdep.c 6.1 83/07/29 */ 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 "../vax/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(TBIS, vaddr + sizeof (struct user)); 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(TBIS, ptob(v)); 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(TBIA, 0); 114 return; 115 } 116 while (size > 0) { 117 mtpr(TBIS, a); 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(TBIA, 0); 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(TBIS, vmmap); 183 c = *(char *)&vmmap[(int)addr & PGOFSET]; 184 mmap[0] = savemap; 185 mtpr(TBIS, vmmap); 186 return (c & 0377); 187 } 188 189 putmemc(addr, val) 190 caddr_t addr; 191 { 192 struct pte savemap; 193 194 savemap = mmap[0]; 195 *(int *)mmap = PG_V | PG_KW | btop(addr); 196 mtpr(TBIS, vmmap); 197 *(char *)&vmmap[(int)addr & PGOFSET] = val; 198 mmap[0] = savemap; 199 mtpr(TBIS, vmmap); 200 } 201 202 /* 203 * Move pages from one kernel virtual address to another. 204 * Both addresses are assumed to reside in the Sysmap, 205 * and size must be a multiple of CLSIZE. 206 */ 207 pagemove(from, to, size) 208 register caddr_t from, to; 209 int size; 210 { 211 register struct pte *fpte, *tpte; 212 213 if (size % CLBYTES) 214 panic("pagemove"); 215 fpte = &Sysmap[btop(from - 0x80000000)]; 216 tpte = &Sysmap[btop(to - 0x80000000)]; 217 while (size > 0) { 218 *tpte++ = *fpte; 219 *(int *)fpte++ = 0; 220 mtpr(TBIS, from); 221 mtpr(TBIS, to); 222 from += NBPG; 223 to += NBPG; 224 size -= NBPG; 225 } 226 } 227