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