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