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: * @(#)vmmac.h 7.1 (Berkeley) 6/4/86 7: */ 8: 9: /* 10: * Virtual memory related conversion macros 11: */ 12: 13: /* Core clicks to number of pages of page tables needed to map that much */ 14: #define ctopt(x) (((x)+NPTEPG-1)/NPTEPG) 15: 16: #ifdef vax 17: /* Virtual page numbers to text|data|stack segment page numbers and back */ 18: #define vtotp(p, v) ((int)(v)) 19: #define vtodp(p, v) ((int)((v) - stoc(ctos((p)->p_tsize)))) 20: #define vtosp(p, v) ((int)(BTOPUSRSTACK - 1 - (v))) 21: #define tptov(p, i) ((unsigned)(i)) 22: #define dptov(p, i) ((unsigned)(stoc(ctos((p)->p_tsize)) + (i))) 23: #define sptov(p, i) ((unsigned)(BTOPUSRSTACK - 1 - (i))) 24: 25: /* Tell whether virtual page numbers are in text|data|stack segment */ 26: #define isassv(p, v) ((v) >= BTOPUSRSTACK - (p)->p_ssize) 27: #define isatsv(p, v) ((v) < (p)->p_tsize) 28: #define isadsv(p, v) ((v) >= stoc(ctos((p)->p_tsize)) && \ 29: (v) < (p)->p_tsize + (p)->p_dsize) 30: #else 31: /* Virtual page numbers to text|data|stack segment page numbers and back */ 32: #define vtotp(p, v) ((int)(v)-LOWPAGES) 33: #define vtodp(p, v) ((int)((v) - stoc(ctos((p)->p_tsize)) - LOWPAGES)) 34: #define vtosp(p, v) ((int)(BTOPUSRSTACK - 1 - (v))) 35: #define tptov(p, i) ((unsigned)(i) + LOWPAGES) 36: #define dptov(p, i) ((unsigned)(stoc(ctos((p)->p_tsize)) + (i) + LOWPAGES)) 37: #define sptov(p, i) ((unsigned)(BTOPUSRSTACK - 1 - (i))) 38: 39: /* Tell whether virtual page numbers are in text|data|stack segment */ 40: #define isassv(p, v) ((v) >= BTOPUSRSTACK - (p)->p_ssize) 41: #define isatsv(p, v) (((v) - LOWPAGES) < (p)->p_tsize) 42: #define isadsv(p, v) (((v) - LOWPAGES) >= stoc(ctos((p)->p_tsize)) && \ 43: !isassv(p, v)) 44: #endif 45: 46: /* Tell whether pte's are text|data|stack */ 47: #define isaspte(p, pte) ((pte) > sptopte(p, (p)->p_ssize)) 48: #define isatpte(p, pte) ((pte) < dptopte(p, 0)) 49: #define isadpte(p, pte) (!isaspte(p, pte) && !isatpte(p, pte)) 50: 51: /* Text|data|stack pte's to segment page numbers and back */ 52: #define ptetotp(p, pte) ((pte) - (p)->p_p0br) 53: #define ptetodp(p, pte) (((pte) - (p)->p_p0br) - (p)->p_tsize) 54: #define ptetosp(p, pte) (((p)->p_addr - (pte)) - 1) 55: 56: #define tptopte(p, i) ((p)->p_p0br + (i)) 57: #define dptopte(p, i) ((p)->p_p0br + ((p)->p_tsize + (i))) 58: #define sptopte(p, i) ((p)->p_addr - (1 + (i))) 59: 60: /* Convert a virtual page number to a pte address. */ 61: #define vtopte(p, v) \ 62: (((v) < (p)->p_tsize + (p)->p_dsize) ? ((p)->p_p0br + (v)) : \ 63: ((p)->p_addr - (BTOPUSRSTACK - (v)))) 64: #ifdef notdef 65: struct pte *vtopte(); 66: #endif 67: 68: /* Bytes to pages without rounding, and back */ 69: #define btop(x) (((unsigned)(x)) >> PGSHIFT) 70: #define ptob(x) ((caddr_t)((x) << PGSHIFT)) 71: 72: /* Turn virtual addresses into kernel map indices */ 73: #define kmxtob(a) (usrpt + (a) * NPTEPG) 74: #define btokmx(b) (((b) - usrpt) / NPTEPG) 75: 76: /* User area address and pcb bases */ 77: #define uaddr(p) (&((p)->p_p0br[(p)->p_szpt * NPTEPG - UPAGES])) 78: #ifdef vax 79: #define pcbb(p) ((p)->p_addr[0].pg_pfnum) 80: #endif 81: 82: /* Average new into old with aging factor time */ 83: #define ave(smooth, cnt, time) \ 84: smooth = ((time - 1) * (smooth) + (cnt)) / (time) 85: 86: /* Abstract machine dependent operations */ 87: #ifdef vax 88: #define setp0br(x) (u.u_pcb.pcb_p0br = (x), mtpr(P0BR, x)) 89: #define setp0lr(x) (u.u_pcb.pcb_p0lr = \ 90: (x) | (u.u_pcb.pcb_p0lr & AST_CLR), \ 91: mtpr(P0LR, x)) 92: #define setp1br(x) (u.u_pcb.pcb_p1br = (x), mtpr(P1BR, x)) 93: #define setp1lr(x) (u.u_pcb.pcb_p1lr = (x), mtpr(P1LR, x)) 94: #define initp1br(x) ((x) - P1PAGES) 95: #endif 96: 97: #define outofmem() wakeup((caddr_t)&proc[2]); 98: 99: /* 100: * Page clustering macros. 101: * 102: * dirtycl(pte) is the page cluster dirty? 103: * anycl(pte,fld) does any pte in the cluster has fld set? 104: * zapcl(pte,fld) = val set all fields fld in the cluster to val 105: * distcl(pte) distribute high bits to cluster; note that 106: * distcl copies everything but pg_pfnum, 107: * INCLUDING pg_m!!! 108: * 109: * In all cases, pte must be the low pte in the cluster, even if 110: * the segment grows backwards (e.g. the stack). 111: */ 112: #define H(pte) ((struct hpte *)(pte)) 113: 114: #if CLSIZE==1 115: #define dirtycl(pte) dirty(pte) 116: #define anycl(pte,fld) ((pte)->fld) 117: #define zapcl(pte,fld) (pte)->fld 118: #define distcl(pte) 119: #endif 120: 121: #if CLSIZE==2 122: #define dirtycl(pte) (dirty(pte) || dirty((pte)+1)) 123: #define anycl(pte,fld) ((pte)->fld || (((pte)+1)->fld)) 124: #define zapcl(pte,fld) (pte)[1].fld = (pte)[0].fld 125: #endif 126: 127: #if CLSIZE==4 128: #define dirtycl(pte) \ 129: (dirty(pte) || dirty((pte)+1) || dirty((pte)+2) || dirty((pte)+3)) 130: #define anycl(pte,fld) \ 131: ((pte)->fld || (((pte)+1)->fld) || (((pte)+2)->fld) || (((pte)+3)->fld)) 132: #define zapcl(pte,fld) \ 133: (pte)[3].fld = (pte)[2].fld = (pte)[1].fld = (pte)[0].fld 134: #endif 135: 136: #ifndef distcl 137: #define distcl(pte) zapcl(H(pte),pg_high) 138: #endif 139: 140: /* 141: * Lock a page frame. 142: */ 143: #define MLOCK(c) { \ 144: while ((c)->c_lock) { \ 145: (c)->c_want = 1; \ 146: sleep((caddr_t)(c), PSWP+1); \ 147: } \ 148: (c)->c_lock = 1; \ 149: } 150: /* 151: * Unlock a page frame. 152: */ 153: #define MUNLOCK(c) { \ 154: if (c->c_want) { \ 155: wakeup((caddr_t)c); \ 156: c->c_want = 0; \ 157: } \ 158: c->c_lock = 0; \ 159: }